-
-
Notifications
You must be signed in to change notification settings - Fork 11k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
unhandled 'error' event in node #18
Comments
@jergason good catch. I can add the error handler. Not sure how the error fits in the reject either. A couple options:
In either case you're going to have to check if an error exists: // option 1
.catch(function (res) {
if (!res.data && res.error) {
console.log('error', res.error);
} else {
console.log('it worked!');
}
});
// option 2
.catch(function (res) {
if (res instanceof Error) {
console.log('error', res);
} else {
console.log('it worked!');
}
}); |
I keep stewing on this, but still don't love either option, and haven't come up with anything else better. Stay tuned... |
Maybe I'm misunderstanding things, but if they're using |
I would expect |
The issue is combing thrown errors and an http response into a single argument. request.js example: var request = require('request');
request('http://www.google.com', function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body) // Print the google web page.
}
}) In this example it's obvious which argument would be an The response argument can be inspected separately, as it's status code might represent an error from a different domain, unrelated to our code's execution. With axios: .catch(function (res) {
// what is res?
// was there an exception?
// can I print a stack trace?
// or do I just need to inspect the status code for 500, etc.?
}); The question is whether A few options:
.catch(function (err) {
if (err instanceof axios.HttpError) {
// determined by status code, no stack trace
// handle non 2xx/3xx response
} else if (err instanceof Error) {
// caused by exception in code
// handle error from code
} else {
// shouldn't get here?
}
}); Another solution would be to follow how request.js does it (not how $http does it), as in don't decide for the developer that a particular http response should cause the promise to be rejected. In request.js, only exceptions in the code populate that </spiel> |
Well explained @jmdobry... That last comment was interesting, but I think I'd recommend against going that direction for two reasons 1) you'd be forced to check the status code in your successful requests which would be annoying (especially in cases where you don't care if it was unsuccessful) 2) a lot of people use and love That second argument is a bit weak I think, but I thought I'd mention it anyway. I think something like this would be reasonable: .catch(function (result) {
if (result.error) {
// caused by exception in code
// handle error from code
} else {
// determined by status code, no stack trace
// handle non 2xx/3xx response
console.log(result.data); // what came back from the server.
}
}); |
@jmdobry request's API doesn't apply to axios, since request is using a single callback to handle success/error. Versus using then/catch a la Promises. Also Promises limit then/catch to a single argument, so whether I like request's API or not, it can't be done the same way with axios. I think I like just rejecting with the .catch(function (res) {
if (res instanceof Error) {
console.log(res.message);
} else {
console.log(res.status, res.data);
}
}); |
Actually it looks like a PR introduced this pattern already: https://github.com/mzabriskie/axios/blob/master/lib/adapters/http.js#L35 Anyone have any heartburn over leaving it this way? I'd prefer not to change an API that people may already depend on in order to resolve this issue. |
I think that it's a totally reasonable/sensible solution 👍 |
@mzabriskie Yes of course. I was just using request's api as a contrasting example to clearly define this issue by showing what axios can't do. I should have been clearer in my comment. |
I'm not doing as much catching up as I should, but the value sent to reject should contain more than just an error (I wasn't very clear before). Very often you'll send a non 2xx status code but still send data. You also may need the headers, etc. I don't think you can just throw an error into the arg and call it good, there's a lot of information about the response you may need in the handler. |
I think that's what @mzabriskie is suggesting with:
|
seems fine to me then |
Yes @kentcdodds sums up the approach correctly. .catch(function (res) {
if (res instanceof Error) {
// In this case a request was never sent to the server
// Something happened in setting up the request that triggered an Error
} else {
// Here the request was made, but the server responded with a status code
// that falls out of the range of 2xx
// You will have the full response details available
console.log(res.data); // The data that the server responded with
console.log(res.headers); // The response headers from the server
console.log(res.status); // The response status code
console.log(res.config); // The config that was used to make the request
}
}); |
👏 totally reasonable api. Thanks again for making this thing dude. |
Thanks everyone for the dialog. I made the change as discussed and it is now on npm. |
When making a request to a url that doesn't exist, axios crashes the server on an unhandled 'error' event.
It looks like the problem is no
req.on('error')
handler on https://github.com/mzabriskie/axios/blob/1d6430f667486ca9de390ccec242114b36c41377/lib/adapters/http.js#L80.I'm not sure the best way to handle an error here though, since it doesn't fit the expected
{data, status, headers, config}
type of message thereject
handler expects.The text was updated successfully, but these errors were encountered: