我正在致力于使用TypeScript的Aurelia CLI项目和致力于对.NET Core/Web API后端进行HTTP调用的aurelia-fetch-client
。如何正确使用自定义Aurelia http-fetch-client拦截器的responseError?
服务器通过返回一个ApiError JSON结果作为API响应的主体,并且状态码在5xx范围内来标准化未处理的异常。
在客户端,我想使用拦截器执行客户端发布这些错误,但添加拦截器是以不希望的方式更改控制流。
这main.ts
相关配置:
function configureContainer(container: Container) {
const http = new HttpClient();
http.configure((config: HttpClientConfiguration) => {
config.useStandardConfiguration()
.withBaseUrl("/api/")
.withInterceptor(new ApiErrorInterceptor(container.get(EventAggregator)));
});
container.registerInstance(HttpClient, http);
}
这是拦截器:
import { autoinject } from "aurelia-framework";
import { EventAggregator } from "aurelia-event-aggregator";
import { Interceptor } from "aurelia-fetch-client";
@autoinject
export class ApiErrorInterceptor implements Interceptor {
constructor(private readonly _aggregator: EventAggregator) {
}
responseError(error: any) {
// do something with the error
return error;
}
}
如果未添加自定义拦截器,则非OK响应记录为错误在Chrome中是这样的:
Unhandled rejection (<{}>, no stack trace)
但是如果拦截器被加入,承诺不会再导致未处理的拒绝错误,并且调用代码继续,就好像承诺已经解决一样,这不是我们想要的,因为它引入了整个应用程序控制流程的巨大变化。
如何实现responseError()
处理程序,以便控制流程与以前一样工作?这甚至是可能的,还是我误解了这个处理程序的目的?
我试着重新抛出返回的错误insteading,但是这不会针对Interceptor接口进行编译。例如,我应该在response()
中这样做吗?
编辑:
这是我们最后使用,望着取出处和相关奥里利亚来源更详细经过。它仅在response()处理程序中处理基于服务器的错误,并在仅响应error()中处理基于客户端的连接错误。
import { autoinject } from "aurelia-framework";
import { EventAggregator } from "aurelia-event-aggregator";
import { Interceptor } from "aurelia-fetch-client";
import { TypedJSON } from "typedjson-npm";
import { EventNames } from "../model/EventNames";
import { ApiError } from "../model/ApiError";
@autoinject
export class ApiErrorInterceptor implements Interceptor {
constructor(private readonly _aggregator: EventAggregator) {
}
async response(response: Response, request?: Request) {
if (!response.ok) {
// publish an error for the response
const apiError = await this.translateToApiError(response.clone());
if (apiError) {
this._aggregator.publish(EventNames.apiError, apiError);
}
}
return response;
}
responseError(error: any) {
// publish errors resulting from connection failure, etc
if (error instanceof Error) {
const apiError = new ApiError();
apiError.statusCode = 0;
apiError.isError = true;
apiError.message = error.message;
this._aggregator.publish(EventNames.apiError, apiError);
}
return error;
}
private async translateToApiError(response: Response): Promise<ApiError> {
let apiError: ApiError | undefined = undefined;
const text = await response.text();
if (text) {
apiError = TypedJSON.parse(text, ApiError);
}
if (!apiError) {
apiError = this.getHttpError(response);
}
return apiError;
}
private getHttpError(response: Response): ApiError {
const apiError = new ApiError();
apiError.isError = true;
apiError.statusCode = response.status;
apiError.message = "Unknown HTTP Error";
switch (apiError.statusCode) {
case 400:
apiError.message = "Bad Request";
break;
case 401:
apiError.message = "Unauthorized Access";
break;
case 404:
apiError.message = "Not Found";
break;
}
if (apiError.statusCode >= 500 && apiError.statusCode < 600) {
apiError.message = "Internal Server Error";
}
return apiError;
}
}
嗨,你看看获取源代码?据我所知,抓取,作为HTTP客户端永远不会拒绝承诺。它将始终调用响应,您必须检查状态码。我认为你正在做的方式(返回错误)是正确的,你只需要处理响应中的错误。 –