Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.
Sign upfeathers rest client (fetch) doesn't convert errors when response body is not JSON #1940
Comments
|
What would the fix look like? Catch the JSON parsing error and throw a Feathers error based on the status code? |
|
I guess so, at least having the proper error constructor and specially the To be honest I don't really understand why the express error handler in the backend is not sending it, in my backend service (custom service) I'm catching the error and rethrowing as NotFoundError (albeit without data). |
|
There is an FAQ entry about this at https://docs.feathersjs.com/help/faq.html#why-am-i-not-getting-json-errors |
|
Yes, I now I can fix it in the backend (I just did, I was returning "undefined" from a db call), but don't you think the client library should be a little more resilient? :) A JSON.parse error is quite a "bad" error to get from an API call, normally in 404 errors there's no need to have a JSON response. The error code has all the needed semantics. In any case you can close this issue if you prefer to do so, at least someone having the same issue will find something to look at and I'll save them the journey through all packages included in @feathers/client. Thanks for your prompt response! |
|
This should definitely still be fixed since it - like you said - still can happen in other instances (e.g. if the load balancer returns a 502 because the backend is down). |
|
I think the proper fix which I can PR for like tomorrow would be to check the content type headers sent in the response instead of assuming it is indeed JSON.
|
|
I believe something like checkStatus (response) {
if (response.ok) {
return response;
}
return response.json().catch(error => {
const toJsonError = new Error('JSON parsing error');
toJsonError.code = response.status;
return toJsonError;
}).then(error => {
error.response = response;
throw error;
});
}Might do it already as well. |
|
It would not be transformed to a Feathers error in that case, if you don't throw? Since you already mapped most status code to custom Errors it would be great to keep that (if it's possible). Otherwise for a quick cheap fix that would be enough as well. I just prefer checking instead of try/catching. :) But I'm not sure if the other transports behave the same way. |
|
Well, with websockets this isn't a problem since you'll always get an object. An improvement with the right error type would be import * as errors from '@feathersjs/errors';
// ...
checkStatus (response) {
if (response.ok) {
return response;
}
return response.json().catch(error => {
const ErrorClass = errors[response.status] || Error;
return new ErrorClass('JSON parsing error');
}).then(error => {
error.response = response;
throw error;
});
} |
Hi
The @feathers/client module which includes itself the @feathers/rest package is not catching correctly errors from the backend that don't return any JSON.
The problem is in the following line:
feathers/packages/rest-client/lib/fetch.js
Line 33 in 98027c4
The "checkStatus" function is checking if the fetch
okproperty is set to true, and assuming that if false the response will be valid JSON. When it isn't, and there's a myriad of possibilities that this may happen, it fails to convert and thus the proper NotFound error is never thrown, and you get instead an ugly JSON parse error.All API calls to a service will fail silently with a JSON parsing error, so there's no way the client can access at least the status code. It's a really simple fix, do you consider accepting a PR for this?