Search code examples
javascriptangularangular-http-interceptors

Angular 9: How show with a HttpInterceptor the stacktrace of a request?


I have a HttpInterceptor and I want for developing purpose print the stack trace of the functions that have made the request:

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);
  }
}

The output of the console log is:

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]

The output don't show any useful information about what component or service has made the request.

There are some tips for show a useful information for find the stack trace of services and components?


Solution

  • The trace inside the interceptor is already messed up. You can also think about using a custom HttpClient. This is untested code though. So if you remove your interceptor provider and replace it with:

    { provide: HttpClient, useClass: TraceHttpClient }
    
    

    And your TraceHttpClient would look like this:

    @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);
      }
    }
    

    You can see a working version here. You can see the stack trace having the different button method calls. You should open the browser console though, because the stackblitz console does not show the console.trace logs.

    The HttpClient calls request for every GET/POST/etc.... So it's enough to just extend that method, and put a trace there, and delegate back to the base HttpClient class