When hitting an HTTP error, Axios only states the HTTP status code in the thrown exception message. I want the exception message to include the request URL, too.
I tried to implement what I want using the following interceptor:
axios.interceptors.response.use(
response => response,
error => {
throw `HTTP ${error.response.status} by ${error.request.url}`;
}
);
The error callback doesn't get triggered upon HTTP errors. Any ideas?
Try to use Promise.reject to replace throw.
The following code works for me. Tested in Chrome.
axios.interceptors.response.use(
function (response) {
return response;
},
function (error) {
return Promise.reject(`HTTP ${error.response.status} by ${error.response.config.url}`);
});
Also, you can simply catch the exception like -
let res = await axios.post(...)
.catch(error => {
console.log(error.response);
console.log(error.request);
});
You have access to all the error details as in interceptor.
Related
Sending a mutation with a bad set of variables (on purpose in this case) results in errors being thrown in the console, and the apollo-link-error link not picking up the error. Additionally, the mutation loading state is stuck as 'loading' and not error object comes through.
Through a debugging session, I fount that the zen-observable global error handling picks up an error thrown in the error-link's "next" function, because 'result' is not defined
pasted the apollo-link-error code that has the observable wrapped in a try catch, but the catch at the bottom here is not the catch that gets hit when if (result.errors) throws a 'nullpointer' because result in undefined.
try {
sub = forward(operation).subscribe({
next: function (result) {
// result is undefined, throwing an error
if (result.errors) {
retriedResult = errorHandler({
graphQLErrors: result.errors,
response: result,
operation: operation,
forward: forward,
});
if (retriedResult) {
retriedSub = retriedResult.subscribe({
next: observer.next.bind(observer),
error: observer.error.bind(observer),
complete: observer.complete.bind(observer),
});
return;
}
}
observer.next(result);
},
error: function (networkError) {
retriedResult = errorHandler({
operation: operation,
networkError: networkError,
graphQLErrors: networkError &&
networkError.result &&
networkError.result.errors,
forward: forward,
});
if (retriedResult) {
retriedSub = retriedResult.subscribe({
next: observer.next.bind(observer),
error: observer.error.bind(observer),
complete: observer.complete.bind(observer),
});
return;
}
observer.error(networkError);
},
complete: function () {
if (!retriedResult) {
observer.complete.bind(observer)();
}
},
});
} // the error is NOT caught here
catch (e) {
errorHandler({ networkError: e, operation: operation, forward: forward });
observer.error(e);
}
```
Link definition:
```javascript
export const client = new ApolloClient({
link: ApolloLink.from([
onError((errors) => {
console.log('errors in link!', errors);
handleServerError(errors);
}),
new MeteorAccountsLink(),
new HttpLink({
uri: '/graphql',
}),
]),
cache: new InMemoryCache(),
});
Edit:
The request in the browser does show a response with an error object with the graphQlErro of shape {errors: [{..}]} which is strange that it's not coming into the 'result' in the link.
Edit 2:
It looks like Meteor is picking up the error thrown in the http link prior to the error posted above, which might be why "result" is undefined. Writing a custom link to polyfill the missing 'result' so the app will at least work.
It seems like an issue with Meteor swallowing the errors. fixed make making a polyfill link to at least not break the js in the mutation complete function and show a general error.
const stupidMeteorErorrPolyfill = new ApolloLink((operation, forward) => forward(operation).map(data => data || { errors: [{ message: '! Empty response in gql links, see graphql.js and network tab' }] }));
I have the following code (simplified for this post) - assume an initial call to onStart().
Running this works fine. If I lose the internet connection I get the net::ERR_INTERNET_DISCONNECTED error (as expected) but the polling stops.
Clearly I am not handling any errors here as that is where I'm getting stuck. I'm not clear where I handle those errors and how? Do I need to call startPolling() again?
I need the polling to continue even if there is no internet connection, so that on re-connection data is updated. Any advice please?
onStart() {
this.startPolling().subscribe(data => {
// do something with the data
});
}
startPolling(): Observable<any> {
return Observable
.interval(10000)
.flatMap(() => this.getData());
}
getData() {
var url = `http://someurl.com/api`;
return this.http.get(url)
.map(response => {
return response.json();
});
}
Thanks in advance.
If you know the error happens because of this.http.get(url) then you can add catch() operator that lets you subscribe to another Observable instead of the source Observable that sent an error notification.
getData() {
var url = `http://someurl.com/api`;
return this.http.get(url)
.catch(err => Observable.empty())
.map(response => {
return response.json();
});
}
This will simply ignore the error and won't emit anything.
I have a problem with angular2 http response.
I want to catch the error in my component.
How does my app work.
In my Component, I Call a function in a personal service :
var response = this.apiUser.login(username, password);
alert(response);
In my Service, I try to auth :
this.http.post(this.httpApiAdress + '/' + this.httpUserAutenticate, body, { headers: contentHeaders })
.subscribe(
response => {
localStorage.setItem('id_token', response.json().token);
this.router.navigate(['home']);
},
error => {
return error.json();
},
() => { }
);
When the auth is ok, all work fine. But when the Auth fail, i can't catch the response in my Component.
(Its undefinied because the alert is executed before the http call...)
Can u help me please !!! (It was working when all the code was only in my Component, but I wanted to slip my code...)
Ty.
Return the observable by using map() instead of subscribe()
return this.http.post(this.httpApiAdress + '/' + this.httpUserAutenticate, body, { headers: contentHeaders })
.map(
response => {
localStorage.setItem('id_token', response.json().token);
this.router.navigate(['home']);
},
);
and then use subscribe where you want to execute code when the response or error arrives
var response = this.apiUser.login(username, password)
.subscribe(
response => alert(response),
error => alert(error),
);
I am new in Angular 2, in my Angular 2 project I create API call service that return json data.
this._http.post(this.url, body, options)
.map(response => response.json())
.catch(this.handleError);
Let say this service return 401 Http Response unauthorized and I tried get the status error, so I can redirect to Login Page and show error message
.subscribe(
login => this.login=login,
error => this.errorMessage = <any>error);
}
but why response code did not throw as error, and only show result
Failed to load resource: the server responded with a status of 401 (Unauthorized) and end the task ?
when I debug the code, the result generated in this line code
this.invoke = function () {
try {
return zone.runTask(self, this, arguments);
}
finally {
drainMicroTaskQueue();
}
};
}
any suggestion ?
Thank You
This question already has answers here:
Angular2 handling http response
(3 answers)
Closed 6 years ago.
I've been using the http error handling strategy used in the angular.io documentation:
getHeroes () {
return this.http.get(this._heroesUrl)
.map(res => <Hero[]> res.json().data)
.catch(this.handleError);
}
private handleError (error: Response) {
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
In some scenarios, instead of a JSON response I will receive a 204 status code (No Data). In this case, the error handler doesn't get invoked until failing to parse the result via res.json(), so the error passed to handleError is "error.json is not a function".
How can I interrogate the response stream to check for a 200 (OK) status code or a response header content-type of "application/json", and signal an error handler with a more relevant error message?
http .get('Some Url') .map(res => {
// If request fails, throw an Error that will be caught
if(res.statu != 200) {
throw new Error('This request has failed ' + res.status); } // If everything went fine, return the response
else {return res.json();
} })
This may help you.
This is just for understanding how to use the status from the response, you can modify according to your requirement.
Error is thrown only for non 200 code check this commit