Closed nouman91 closed 1 year ago
I also want to get the status code as well.
assuming you're using fetchBaseQuery, request and response objects are attached to action.meta.baseQueryMeta - this presumably will have the URL and status information you want.
proving this in typescript will probably be a little harder, without some type assertions.
@EskiMojo14 Thank you for your response thing is I am not seeing this information. Here is the full code:
Api Slice
export const someApiSlice = createApi({
baseQuery: fetchBaseQuery({
baseUrl: getExternalUrlPath(),
prepareHeaders: prepareHeaders,
}),
endpoints: () => ({}),
reducerPath: 'sites',
})
Api Queries
export const someApi = someApiSlice.injectEndpoints({
endpoints: (builder) => ({
getSites: builder.query<InfTO, string[]>({
query: () => ({
url: 'some-url',
}),
transformResponse: (res: { info: InfoTO[] }, _, args) => {
const result: InfoTO = res.info.reduce((prev, curr) => {
const { site_id, ...rest } = curr;
if (args.indexOf(site_id) >= 0) {
return { ...prev, [site_id]: { ...rest } };
}
return prev;
}, {});
return result;
},
}),
}),
});
Error Middleware
export const errorMiddleware: Middleware = (store) => (next) => (action) => {
*/
const conditionError = 'ConditionError';
/**If we got actual rejection from the APIs than show a toast */
if (
isRejectedWithValue(action) ||
(action.type.endsWith('/rejected') && action.error.name !== conditionError)
) {
console.log(action);
console.log(store);
store.dispatch(showToast({ message: getErrorMessage(action.error), type: 'error' }));
}
return next(action);
};
Console Output
{
"type": "**/**/**",
"meta": {
"arg": [
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"f3e3d7af-97cd-4a06-93d2-aae9cee5b276",
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"f3e3d7af-97cd-4a06-93d2-aae9cee5b276",
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"993f79f8-fead-42cd-9e7d-70d848e2e1a9",
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"37b569fc-c67a-496d-8d65-88fc1adb9ace",
"37b569fc-c67a-496d-8d65-88fc1adb9ace",
"f3e3d7af-97cd-4a06-93d2-aae9cee5b276",
"37b569fc-c67a-496d-8d65-88fc1adb9ace"
],
"requestId": "BB6CgUBQ-NLfAiLhlEmrE",
"rejectedWithValue": false,
"requestStatus": "rejected",
"aborted": false,
"condition": false
},
"error": {
"name": "Error",
"message": "Request failed with status code 404",
"stack": "Error: Request failed with status code 404\n at createError (http://localhost:6014/vendors~main.iframe.bundle.js:201591:15)\n at settle (http://localhost:6014/vendors~main.iframe.bundle.js:201891:12)\n at XMLHttpRequest.onloadend (http://localhost:6014/vendors~main.iframe.bundle.js:200903:7)"
}
}
that doesn't look like a RTKQ action, the type would be ${api.reducerPath}/executeQuery/rejected
and the arg would have { type: 'query' }
. (also that looks like it's using XMLHttpRequest, which fetchBaseQuery definitely doesn't do)
do you have any other createAsyncThunk calls that might be having that error instead?
@EskiMojo14 Yes, the type is what you mention and I just quickly redacted it to put the comment faster. Rest is the complete setup of the APIs that I had. Can you point me to where the problem is by looking into the code? I formatted my old comment to make it easier to read.
Are you sure? The argument doesn't look right - it would be something like { type: 'query', originalArgs: [...ids], endpointName: 'getSites', queryCacheKey: 'getSites([...ids])' }
Would you be able to record a Replay or create a reproduction in CodeSandbox?
Update: Upon further investigation, I found out when API returns 404 the error object does not get the full information like for other error types:
404 Error Object
{
"type": "*/*/*",
"meta": {
"arg": [
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"f3e3d7af-97cd-4a06-93d2-aae9cee5b276",
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"f3e3d7af-97cd-4a06-93d2-aae9cee5b276",
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"993f79f8-fead-42cd-9e7d-70d848e2e1a9",
"4968f80d-70d9-4222-90e6-a42778bc49c4",
"37b569fc-c67a-496d-8d65-88fc1adb9ace",
"37b569fc-c67a-496d-8d65-88fc1adb9ace",
"f3e3d7af-97cd-4a06-93d2-aae9cee5b276",
"37b569fc-c67a-496d-8d65-88fc1adb9ace"
],
"requestId": "URqM0fT50Tl-xqsDFZlyB",
"rejectedWithValue": false,
"requestStatus": "rejected",
"aborted": false,
"condition": false
},
"error": {
"name": "Error",
"message": "Request failed with status code 404",
"stack": "Error: Request failed with status code 404\n at createError (http://localhost:6014/vendors~main.iframe.bundle.js:202592:15)\n at settle (http://localhost:6014/vendors~main.iframe.bundle.js:202892:12)\n at XMLHttpRequest.onloadend (http://localhost:6014/vendors~main.iframe.bundle.js:201904:7)"
}
}
422 Error Object
{
"type": "*/*/*",
"payload": {
"status": 422,
"data": {
"error_code": 10202,
"error_message": "Invalid ids",
"module_name": ""
}
},
"meta": {
"baseQueryMeta": {
"request": {},
"response": {}
},
"RTK_autoBatch": true,
"arg": {
"type": "query",
"subscribe": true,
"subscriptionOptions": {
"pollingInterval": 0
},
"endpointName": "get",
"originalArgs": [
"14bfa34d-e087-4147-b73a-18417e290e1b",
"a35184c6-5ed0-4c95-a20e-93bba7024de3"
],
"queryCacheKey": "get**([\"14bfa34d-e087-4147-b73a-18417e290e1b\",\"a35184c6-5ed0-4c95-a20e-93bba7024de3\"])"
},
"requestId": "LdzC9JPKVTvqo44nq6MOo",
"rejectedWithValue": true,
"requestStatus": "rejected",
"aborted": false,
"condition": false
},
"error": {
"message": "Rejected"
}
}
I am however still not seeing the URL for the request though.
it'll be action.meta.baseQueryMeta.request.url, Request instances just aren't serializeable.
@EskiMojo14 I see it there, but any idea why 404 is not behaving correctly?
none - like i said, there's nothing in that action that suggests it's actually an action from RTKQ, and the stack mentioning XMLHttpRequest is especially odd for something supposedly using fetch.
Thank you @EskiMojo14 for being so responsive and helpful, I appreciate it.
In my use case, I want to get all the API errors in error middleware and display them to the user. So far I have been encountering a few problems regarding accessing the error message. A few of the APIs have error messages in the error. message field but few have only 'rejected' in error. message field. I am not sure why is that and which field should I be using to access the error message.
The error object in question:
{
"type": "api/executeQuery/rejected",
"payload": {
"status": 422,
"data": {
"error_code": 10202,
"error_message": "Invalid ",
"module_name": "**"
}
},
"meta": {
"baseQueryMeta": {
"request": {},
"response": {}
},
"RTK_autoBatch": true,
"arg": {
"type": "query",
"subscribe": true,
"subscriptionOptions": {
"pollingInterval": 0
},
"endpointName": "**",
"originalArgs": [
"14bfa34d-e087-4147-b73a-18417e290e1b",
"a35184c6-5ed0-4c95-a20e-93bba7024de3"
],
"queryCacheKey": "**([\"14bfa34d-e087-4147-b73a-18417e290e1b\",\"a35184c6-5ed0-4c95-a20e-93bba7024de3\"])"
},
"requestId": "9E6Tp-e6iIQKShfmLp0Ye",
"rejectedWithValue": true,
"requestStatus": "rejected",
"aborted": false,
"condition": false
},
"error": {
"message": "Rejected"
}
}
For errors that have been rejectedWithValue, the error will be located at action.payload. For RTKQ, this is used for any "handled" errors (i.e. the base query has returned { error } because the request failed). This will be a FetchBaseQueryError in the case of fetchBaseQuery.
The only time with RTKQ that you'll get errors not rejectedWithValue is for uncaught errors in the process of executing the endpoint - this usually indicates that something went significantly wrong with one of your endpoint settings - or for condition rejections (which in the context of RTKQ means you're subscribing to a cached result and don't need to fetch it).
Therefore, you can safely use isRejectedWithValue to match actions (along with checking the meta looks like a RTKQ action) and action.payload will be the actual error value.
Ok, Make sense. Let me see my setup and configure error handling accordingly to what you have shared here.
Do you think 404's error handling issue is a legit issue and needs to be looked at? For the 404 case, I don't get the necessary information. Let me know if you need any details on it.
If you can provide enough code to replicate it, or record it happening like i asked, then yes it might be an issue needing looking into.
Until then, I'm not convinced it's RTKQ related as it's entirely the wrong shape (and removing the action type doesn't fill me with confidence either).
ok, I will try to record it and post the results here.
Here's a codesandbox, showing a 404 being correctly caught.
You can also see that action.meta.baseQueryMeta.request.url
is the url, and the status is at action.meta.baseQueryMeta.response.status
as well as action.payload.status
.
I am using a pretty standard implementation of RTK query from the docs nothing too fancy. I have a situation where I would want to know the API URL that failed in the error middleware.
I checked in the docs and few other sites but could not find it. Here is my error middleware:
`export const errorMiddleware: Middleware = (store) => (next) => (action) => { /**Rejection from interal redux cache we want to ignore it since it is not a rejection:
*/ const conditionError = 'ConditionError'; /*If we got actual rejection from the APIs than show a toast / if ( isRejectedWithValue(action) || (action.type.endsWith('/rejected') && action.error.name !== conditionError) ) { console.log(action.meta.url???? ); console.log(store); store.dispatch( showToast({ message: action.error.message, type: 'error' }) ); } return next(action); }; ; `