Angular 9: 如何使用 HttpInterceptor 显示请求的堆栈跟踪?
Angular 9: How show with a HttpInterceptor the stacktrace of a request?
我有一个 HttpInterceptor,出于开发目的,我想打印发出请求的函数的堆栈跟踪:
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class HttpInterceptorService implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('Who has made this request?', new Error().stack);
return next.handle(request);
}
}
控制台日志的输出为:
at HttpInterceptorService.intercept (:4200/main.js:1344) [angular]
at HttpInterceptorHandler.handle (:4200/vendor.js:30718) [angular]
at HttpXsrfInterceptor.intercept (:4200/vendor.js:31484) [angular]
at HttpInterceptorHandler.handle (:4200/vendor.js:30718) [angular]
at HttpInterceptingHandler.handle (:4200/vendor.js:31549) [angular]
at MergeMapSubscriber.project (:4200/vendor.js:30457) [angular]
at MergeMapSubscriber._tryNext (:4200/vendor.js:112207) [angular]
at MergeMapSubscriber._next (:4200/vendor.js:112197) [angular]
at MergeMapSubscriber.next (:4200/vendor.js:107493) [angular]
at Observable._subscribe (:4200/vendor.js:116912) [angular]
at Observable._trySubscribe (:4200/vendor.js:106949) [angular]
at Observable.subscribe (:4200/vendor.js:106935) [angular]
at MergeMapOperator.call (:4200/vendor.js:112182) [angular]
at Observable.subscribe (:4200/vendor.js:106930) [angular]
输出没有显示任何有关发出请求的组件或服务的有用信息。
有一些提示可以显示查找服务和组件堆栈跟踪的有用信息吗?
拦截器里面的trace已经乱七八糟了。您也可以考虑使用自定义 HttpClient
。这是未经测试的代码。因此,如果您删除拦截器提供程序并将其替换为:
{ provide: HttpClient, useClass: TraceHttpClient }
你的 TraceHttpClient
看起来像这样:
@Injectable()
export class TraceHttpClient extends HttpClient {
constructor(handler: HttpHandler) {
super(handler);
}
request(...args: [ any ]): Observable<any> {
console.trace('Who has made this request?');
return super.request(...args);
}
}
您可以看到一个工作版本 here。您可以看到具有不同按钮方法调用的堆栈跟踪。不过,您应该打开浏览器控制台,因为 stackblitz 控制台不显示 console.trace
日志。
HttpClient
为每个 GET/POST/etc 调用 request
... 所以只要扩展该方法就足够了,在那里放置一个跟踪,然后委托回基础 HttpClient
class
这是已接受答案的替代方案。我不希望每次 http 调用都发出堆栈的噪音。
一旦进入 HttpClient 错误处理程序,堆栈跟踪就会丢失,因此 console.trace
无效。 Errors
很贵,所以我不想在生产中使用它。
/**
* Extended HttpClient that generates a stack trace on error when not in a production build.
*/
@Injectable()
export class TraceHttpClient extends HttpClient {
constructor(handler: HttpHandler) {
super(handler);
}
request(...args: [ any ]): Observable<any> {
const stack = environment.production ? null : (Error()).stack;
return super.request(...args).pipe(catchError((err) => {
// tslint:disable-next-line:no-console
if(stack) console.error('Cloud UI - HTTP Client error stack\n', stack);
return throwError(err);
}));
}
}
我有一个 HttpInterceptor,出于开发目的,我想打印发出请求的函数的堆栈跟踪:
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class HttpInterceptorService implements HttpInterceptor {
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
console.log('Who has made this request?', new Error().stack);
return next.handle(request);
}
}
控制台日志的输出为:
at HttpInterceptorService.intercept (:4200/main.js:1344) [angular]
at HttpInterceptorHandler.handle (:4200/vendor.js:30718) [angular]
at HttpXsrfInterceptor.intercept (:4200/vendor.js:31484) [angular]
at HttpInterceptorHandler.handle (:4200/vendor.js:30718) [angular]
at HttpInterceptingHandler.handle (:4200/vendor.js:31549) [angular]
at MergeMapSubscriber.project (:4200/vendor.js:30457) [angular]
at MergeMapSubscriber._tryNext (:4200/vendor.js:112207) [angular]
at MergeMapSubscriber._next (:4200/vendor.js:112197) [angular]
at MergeMapSubscriber.next (:4200/vendor.js:107493) [angular]
at Observable._subscribe (:4200/vendor.js:116912) [angular]
at Observable._trySubscribe (:4200/vendor.js:106949) [angular]
at Observable.subscribe (:4200/vendor.js:106935) [angular]
at MergeMapOperator.call (:4200/vendor.js:112182) [angular]
at Observable.subscribe (:4200/vendor.js:106930) [angular]
输出没有显示任何有关发出请求的组件或服务的有用信息。
有一些提示可以显示查找服务和组件堆栈跟踪的有用信息吗?
拦截器里面的trace已经乱七八糟了。您也可以考虑使用自定义 HttpClient
。这是未经测试的代码。因此,如果您删除拦截器提供程序并将其替换为:
{ provide: HttpClient, useClass: TraceHttpClient }
你的 TraceHttpClient
看起来像这样:
@Injectable()
export class TraceHttpClient extends HttpClient {
constructor(handler: HttpHandler) {
super(handler);
}
request(...args: [ any ]): Observable<any> {
console.trace('Who has made this request?');
return super.request(...args);
}
}
您可以看到一个工作版本 here。您可以看到具有不同按钮方法调用的堆栈跟踪。不过,您应该打开浏览器控制台,因为 stackblitz 控制台不显示 console.trace
日志。
HttpClient
为每个 GET/POST/etc 调用 request
... 所以只要扩展该方法就足够了,在那里放置一个跟踪,然后委托回基础 HttpClient
class
这是已接受答案的替代方案。我不希望每次 http 调用都发出堆栈的噪音。
一旦进入 HttpClient 错误处理程序,堆栈跟踪就会丢失,因此 console.trace
无效。 Errors
很贵,所以我不想在生产中使用它。
/**
* Extended HttpClient that generates a stack trace on error when not in a production build.
*/
@Injectable()
export class TraceHttpClient extends HttpClient {
constructor(handler: HttpHandler) {
super(handler);
}
request(...args: [ any ]): Observable<any> {
const stack = environment.production ? null : (Error()).stack;
return super.request(...args).pipe(catchError((err) => {
// tslint:disable-next-line:no-console
if(stack) console.error('Cloud UI - HTTP Client error stack\n', stack);
return throwError(err);
}));
}
}