question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

HttpClient Interceptor triggers before HttpResponse gets processed

See original GitHub issue

Hello,

I have the following problem: I would like to handle all my error responses inside a HttpInterceptor. Unfortunately the HttpInterceptor catch method triggers before the catch method inside the generated typescripe service. Consequently, I only have access on the HttpErrorResponse object, with a blob as error body and not the desired list of strings.

I tried to provide the intereceptor after the clients from the generated typescript, but without success.

Is it possible to trigger the interceptor after catch/transform of the generated typescript service?

Api-Controller:

[HttpGet("test/{input}")]
[ProducesResponseType(typeof(object), 200)]
[ProducesResponseType(typeof(string[]), 400)]
public IActionResult Test(string input)
{
   if (input == "error")
      return BadRequest(new [] { "error1", "error2"});
   return Ok(new {Test = "ok"});
}

Generated typescript:

test(input: string): Observable<any> {
	let url_ = this.baseUrl + "/api/Home/test/{input}";
	if (input === undefined || input === null)
		throw new Error("The parameter 'input' must be defined.");
	url_ = url_.replace("{input}", encodeURIComponent("" + input)); 
	url_ = url_.replace(/[?&]$/, "");

	let options_ : any = {
		observe: "response",
		responseType: "blob",
		headers: new HttpHeaders({
			"Content-Type": "application/json", 
			"Accept": "application/json"
		})
	};

	return this.http.request("get", url_, options_).flatMap((response_ : any) => {
		return this.processTest(response_);
	}).catch((response_: any) => {
		if (response_ instanceof HttpResponse) {
			try {
				return this.processTest(response_);
			} catch (e) {
				return <Observable<any>><any>Observable.throw(e);
			}
		} else
			return <Observable<any>><any>Observable.throw(response_);
	});
}
...

HttpInterceptor:

@Injectable()
export class AnotherInterceptor implements HttpInterceptor {
    public intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpResponse<any>> | Observable<HttpEvent<any>> {
        return next.handle(req).catch((response) => {
            if (response instanceof HttpErrorResponse) {
                if (response.status === 400) {
                    // show response.error string[] in alert
                }
            }
            return Observable.throw(response);
        });
    }
}

BR Jakob

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:1
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
jmajnekcommented, May 19, 2018

Dear @RSuter, I think you can close this issue because as far as I know it is impossible.

I created a question here Stackoverflow. If I find an answer and it is necessary I will re-open this issue later.

Thank you!

0reactions
ranoufcommented, Aug 3, 2018

I have a part of your answer:

this allow me to convert the FileReader for the blob as an observable:

const readFile = (blob: Blob): Observable<string> => Observable.create(obs => {
  if (!(blob instanceof Blob)) {
    obs.error(new Error('`blob` must be an instance of File or Blob.'));
    return;
  }
  debugger; //this one not
  const reader = new FileReader();

  reader.onerror = err => obs.error(err);
  reader.onabort = err => obs.error(err);
  reader.onload = () => obs.next(reader.result);
  reader.onloadend = () => obs.complete();

  return reader.readAsText(blob);
});

From what I read, we can use Map to chaining the Observable like this:

 intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return next.handle(request).do((event: HttpEvent<any>) => {
      if (event instanceof HttpResponse) {
        console.log(request);
        // do stuff with response if you want
      }
    }, (err: any) => {

      if (err instanceof HttpErrorResponse) {
        debugger; //This one works
        return readFile(err.error).map(value => {
          debugger; //this one not
          return value;
        });
      }
    }
    );
  }
}

But I made a mistake somewhere because I can enter in the first debbuger but never in the 2 other one.

Maybe together we can find a way to make it work? 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

HttpClient Interceptor triggers before HttpResponse gets ...
Hello, I have the following problem: I would like to handle all my error responses inside a HttpInterceptor.
Read more >
HTTP - Intercept requests and responses
The intercept method transforms a request into an Observable that eventually returns the HTTP response. In this sense, each interceptor is fully capable...
Read more >
HttpInterceptor->Service->HttpClient Cyclic Dependency
So I have my authentication service, AuthService, that basically has two methods, one that gets a new token from the server, given a...
Read more >
Angular Interceptors to Manage HTTP Requests ⚡
Learn how to use Angular interceptors to manage HTTP requests including JWT authorization , caching and logging.
Read more >
Top 10 ways to use Interceptors in Angular
My ten favorite ways to use the interceptor in Angular. With examples of error handling, profiling, caching and more this list will inspire...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found