Angular: невозможно вернуть пользовательское сообщение об ошибке через HttpResponse
Я гуглил обходной путь и видел примеры, когда мы возвращаем текст ошибки в действии контроллера как ActionResult
/JsonResult
или используя HttpRequest
подход следующим образом
HttpContext.Current.Response.Status = "error text";
Для моего фонового приложения я использую ASP.NET Core 2.1.1
а также .Status
собственность отсутствует в HttpResponse
учебный класс.
Кроме того, я не могу найти какие-либо свойства, которые могут содержать мое собственное сообщение об ошибке.
Я использую промежуточный класс, который получает описание исключения и передает его как JSON
Startup.cs
app.UseMiddleware<ExceptionHandleMiddleware>();
Сам класс
public class ExceptionHandleMiddleware
{
private readonly RequestDelegate next;
public ExceptionHandleMiddleware(RequestDelegate next)
{
this.next = next ?? throw new ArgumentNullException(nameof(next));
}
public async Task Invoke(HttpContext context)
{
try
{
await next(context);
}
catch (Exception ex)
{
context.Response.Clear();
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
context.Response.ContentType = "application/json";
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
await context.Response.WriteAsync(JsonConvert.SerializeObject(new { error = $"{ex.GetType().FullName}: '{ex.Message}'" }));
}
}
}
Посмотрите на линию
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
Это необходимо, потому что в моем приложении Angular 6 я использую HttpInterceptor
и, чтобы поймать ошибку, вы должны вернуть ошибку HTTP (в противном случае .catch(...)
блок не запускается в угловом перехватчике).
Вот немного из моего приложения Angular
@Injectable()
export class ErrorHandlerInterceptor implements HttpInterceptor {
constructor(
private notify: NgNotify,
) { }
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next
.handle(req)
.catch(this.handleError)
}
...
Хотя context.Response.WriteAsync(...)
бит возвращает текст исключения, я не могу извлечь его в .catch(...)
блок перехватчика.
public handleError = (error: Response) => {
Вот error
напечатано как JSON
(обратите внимание, что в нем отсутствует сообщение об ошибке "Последняя запись")
{
"headers":{
"normalizedNames":{
},
"lazyUpdate":null
},
"status":500,
"statusText":"OK",
"url":"https://localhost:44305/api/Entry/GetNext?id=11962",
"ok":false,
"name":"HttpErrorResponse",
"message":"Http failure response for https://localhost:44305/api/Entry/GetNext?id=11962: 500 OK",
"error":{
}
}
Тем не менее, если я открою вкладку Chrome Network, я вижу следующее
Таким образом, я не могу получить этот текст ошибки из error: Response
,
Может быть, кто-то знает лучший способ передачи ошибки клиенту Angular и извлечения ее там?
Обновление 1 - обработчик ошибок (я поставил только точку останова, чтобы исследовать содержимое ошибки)
public handleError = (error: Response) => {
debugger
return Observable.throw(error)
}
1 ответ
Мой недосмотр.
Если вы посмотрите на JSON вернулся
....
"message":"Http failure response for https://localhost:44305/api/Entry/GetNext?id=11962: 500 OK",
"error":{
}
}
error
кажется пустым объектом
ПО ФАКТУ error
это Blob
который мы должны прочитать следующим образом
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next
.handle(req)
.catch(this.handleError)
}
public handleError = (error: Response) => {
let reader = new FileReader();
let ngNotify = this._ngNotify;
reader.onload = function () {
var result = JSON.parse(this.result);
ngNotify.nofity('Error', result.error);
};
reader.readAsText(error['error']);
return Observable.throw(error)
}
И это все.
Я в конечном итоге решить эту проблему путем реализации промежуточного программного обеспечения для перехвата HttpResponse
, извлеките ошибку из BLOB-объекта и верните сообщение в json. Благодаря вкладу Яапа Моссельмана.