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. Благодаря вкладу Яапа Моссельмана.

Другие вопросы по тегам