Reputation: 3474
I have a situation where the web services that I am using are inconsistently coded and I have no way to change their behavior. My main issue is that the web service returns an HTTP 404
error on a valid GET
method in cases where there are no records within the backend database corresponding to the conditions of the query. The correct behavior should be a 200
HTTP response with an empty array of elements (e.g. list of companies).
I have an Angular interceptor
with a catchError
function that I've coded to recognize cases where the 404 really isn't an error. Within this logic I want to suppress the error and return a response
that contains body: {companies: []}
.
Is there a way to do this?
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
public intercept(request: { clone: (arg0: { headers: any; }) => any; headers: { set: (arg0: string, arg1: string) => any; }; }, next: { handle: (arg0: any) => any; }) {
...
return next.handle(request.clone({headers})).pipe(
// retry(1),
catchError((error: HttpErrorResponse) => {
let message;
if (error.error instanceof ErrorEvent) {
message = `Client error: ${error.error.message}`;
}
else {
message = `Server code: ${error.status}\nMessage: ${error.message}`;
// detect 404 error that aren't really errors
if (404 === error.status && [Webservices.GET_MEMBER_COMPANIES, Webservices.GET_MEMBER_PERSONS, Webservices.GET_MEMBER_PERSON_COMPANY_LINKS, Webservices.GET_MEMBER_VISUALIZATION_STATES].some((path: string) => {
return (new RegExp(path.replace(Webservices.MEMBER_ID, '\\d+').replace(Webservices.COMPANY_ID, '\\d+').replace(Webservices.PERSON_ID, '\\d+').replace(Webservices.VISUALIZATION_STATE_ID, '\\d+'))).test(error.url);
})) {
console.debug(error);
}
}
console.debug(headers);
console.debug(message);
// window.alert(message);
return throwError(message);
})
);
}
}
Note: the above is a work in progress provided solely to illustrate the state of the error handler
Thanks!
Upvotes: 0
Views: 3221
Reputation: 176
Inside your catchError you need to return an Observable<HttpResponse>
. Try this:
import {of} from 'rxjs'; //Add this
catchError((error: HttpErrorResponse) => {
if (404 === error.status){
var response = new HttpResponse({
body: {companies: []} //your body object
});
return of(response);
}
return throwError(message);
}
Explanation: if you look at interceptor signature (HttpEvent) intercept(req:HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>>
the return type is Observable<HttpEvent<any>>
which is an Angular type defined as:
type HttpEvent<T> = HttpSentEvent | HttpHeaderResponse | HttpResponse<T> | HttpProgressEvent | HttpUserEvent<T>;
So build your HttpResponse variable and use of operator to return it as Observable.
That's all.
Upvotes: 4