I have a data service that looks like this:
@Injectable()
export class DataService {
baseUrl = 'http://localhost'
constructor(
private httpClient: HttpClient) {
}
get(url, params): Promise<Object> {
return this.sendRequest(this.baseUrl + url, 'get', null, params)
.map((res) => {
return res as Object
})
.toPromise();
}
post(url, body): Promise<Object> {
return this.sendRequest(this.baseUrl + url, 'post', body)
.map((res) => {
return res as Object
})
.toPromise();
}
patch(url, body): Promise<Object> {
return this.sendRequest(this.baseUrl + url, 'patch', body)
.map((res) => {
return res as Object
})
.toPromise();
}
sendRequest(url, type, body, params = null): Observable<any> {
return this.httpClient[type](url, { params: params }, body)
}
}
If I get an HTTP error (i.e. 404), I get a nasty console message: ERROR Error: Uncaught (in promise): [object Object] from core.es5.js How do I handle it in my case?
You have some options, depending on your needs. If you want to handle errors on a per-request basis, add a
catch
to your request. If you want to add a global solution, useHttpInterceptor
.Open here the working demo plunker for the solutions below.
tl;dr
In the simplest case, you'll just need to add a
.catch()
or a.subscribe()
, like:But there are more details to this, see below.
Method (local) solution: log error and return fallback response
If you need to handle errors in only one place, you can use
catch
and return a default value (or empty response) instead of failing completely. You also don't need the.map
just to cast, you can use a generic function. Source: Angular.io - Getting Error Details.So, a generic
.get()
method, would be like:Handling the error will allow you app to continue even when the service at the URL is in bad condition.
This per-request solution is good mostly when you want to return a specific default response to each method. But if you only care about error displaying (or have a global default response), the better solution is to use an interceptor, as described below.
Run the working demo plunker here.
Advanced usage: Intercepting all requests or responses
Once again, Angular.io guide shows:
Which, of course, can be used to handle errors in a very simple way (demo plunker here):
Providing your interceptor: Simply declaring the
HttpErrorInterceptor
above doesn't cause your app to use it. You need to wire it up in your app module by providing it as an interceptor, as follows:Note: If you have both an error interceptor and some local error handling, naturally, it is likely that no local error handling will ever be triggered, since the error will always be handled by the interceptor before it reaches the local error handling.
Run the working demo plunker here.