diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/Microsoft/AspNetCore/Mvc/SseAsyncEnumerableResult.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/Microsoft/AspNetCore/Mvc/SseAsyncEnumerableResult.cs index f44e8f911..11eb46992 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/Microsoft/AspNetCore/Mvc/SseAsyncEnumerableResult.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/Microsoft/AspNetCore/Mvc/SseAsyncEnumerableResult.cs @@ -1,7 +1,12 @@ using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Threading.Tasks; +using Volo.Abp.AspNetCore.ExceptionHandling; +using Volo.Abp.Http; +using Volo.Abp.Json; namespace Microsoft.AspNetCore.Mvc; public class SseAsyncEnumerableResult : IActionResult @@ -22,21 +27,45 @@ public class SseAsyncEnumerableResult : IActionResult try { + var jsonSerializer = context.HttpContext.RequestServices.GetRequiredService(); + await foreach (var content in _asyncEnumerable) { if (!string.IsNullOrEmpty(content)) { - await response.WriteAsync($"data: {content}\n\n"); + var sseResult = new SseResult(content); + await response.WriteAsync($"data: {jsonSerializer.Serialize(sseResult)}\n\n"); await response.Body.FlushAsync(); } } - await response.WriteAsync("data: [DONE]\n\n"); + await response.WriteAsync($"data: {jsonSerializer.Serialize(new SseResult("FINISHED"))}\n\n"); await response.Body.FlushAsync(); } catch (OperationCanceledException) { // ignore } + catch (Exception ex) + { + var exceptionHandlingOptions = context.HttpContext.RequestServices.GetRequiredService>().Value; + var exceptionToErrorInfoConverter = context.HttpContext.RequestServices.GetRequiredService(); + var remoteServiceErrorInfo = exceptionToErrorInfoConverter.Convert(ex, options => + { + options.SendExceptionsDetailsToClients = exceptionHandlingOptions.SendExceptionsDetailsToClients; + options.SendExceptionDataToClientTypes = exceptionHandlingOptions.SendExceptionDataToClientTypes; + options.SendStackTraceToClients = exceptionHandlingOptions.SendStackTraceToClients; + }); + + response.Headers.RemoveAll(x => x.Key == "Content-Type"); + response.Headers.Append("Content-Type", "application/json"); + response.Headers.Append(AbpHttpConsts.AbpErrorFormat, "true"); + response.StatusCode = (int)context.HttpContext.RequestServices + .GetRequiredService() + .GetStatusCode(context.HttpContext, ex); + + await response.WriteAsJsonAsync(remoteServiceErrorInfo); + await response.Body.FlushAsync(); + } } } diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/Microsoft/AspNetCore/Mvc/SseAsyncEnumerableResultFilter.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/Microsoft/AspNetCore/Mvc/SseAsyncEnumerableResultFilter.cs index 55d20014e..0c1f2c8e4 100644 --- a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/Microsoft/AspNetCore/Mvc/SseAsyncEnumerableResultFilter.cs +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/Microsoft/AspNetCore/Mvc/SseAsyncEnumerableResultFilter.cs @@ -5,7 +5,7 @@ using System.Threading.Tasks; namespace Microsoft.AspNetCore.Mvc; public class SseAsyncEnumerableResultFilter : IAsyncActionFilter { - public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) + public async virtual Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next) { var executedContext = await next(); diff --git a/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/Microsoft/AspNetCore/Mvc/SseResult.cs b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/Microsoft/AspNetCore/Mvc/SseResult.cs new file mode 100644 index 000000000..7225d6fc7 --- /dev/null +++ b/aspnet-core/modules/ai/LINGYUN.Abp.AIManagement.HttpApi/Microsoft/AspNetCore/Mvc/SseResult.cs @@ -0,0 +1,13 @@ +using System.Text.Json.Serialization; + +namespace Microsoft.AspNetCore.Mvc; + +public class SseResult +{ + [JsonPropertyName("m")] + public string Message { get; } + public SseResult(string message) + { + Message = message; + } +}