Error Handling
Overview
If your query or mutation happens to throw an error when using fetchBaseQuery, it will be returned in the error
property of the respective hook. The component will re-render when that occurs, and you can show appropriate UI based on the error data if desired.
Error Display Examples
function PostsList() {
const { data, error } = useGetPostsQuery()
return (
<div>
{error.status} {JSON.stringify(error.data)}
</div>
)
}
function AddPost() {
const [addPost, { error }] = useAddPostMutation()
return (
<div>
{error.status} {JSON.stringify(error.data)}
</div>
)
}
If you need to access the error or success payload immediately after a mutation, you can chain .unwrap()
.
addPost({ id: 1, name: 'Example' })
.unwrap()
.then((payload) => console.log('fulfilled', payload))
.catch((error) => console.error('rejected', error))
function PostsList() {
const { error } = useSelector(api.endpoints.getPosts.select())
return (
<div>
{error.status} {JSON.stringify(error.data)}
</div>
)
}
Errors with a custom baseQuery
Whether a response is returned as data
or error
is dictated by the baseQuery
provided.
Ultimately, you can choose whatever library you prefer to use with your baseQuery
, but it's important that you return the correct response format. If you haven't tried fetchBaseQuery
yet, give it a chance! Otherwise, see Customizing Queries for information on how to alter the returned errors.
Handling errors at a macro level
There are quite a few ways that you can manage your errors, and in some cases, you may want to show a generic toast notification for any async error. Being that RTK Query is built on top of Redux and Redux-Toolkit, you can easily add a middleware to your store for this purpose.
Redux Toolkit has action matching utilities that we can leverage for additional custom behaviors.
- TypeScript
- JavaScript
import { isRejectedWithValue } from '@reduxjs/toolkit'
import type { MiddlewareAPI, Middleware } from '@reduxjs/toolkit'
import { toast } from 'your-cool-library'
/**
* Log a warning and show a toast!
*/
export const rtkQueryErrorLogger: Middleware =
(api: MiddlewareAPI) => (next) => (action) => {
// RTK Query uses `createAsyncThunk` from redux-toolkit under the hood, so we're able to utilize these matchers!
if (isRejectedWithValue(action)) {
console.warn('We got a rejected action!')
toast.warn({ title: 'Async error!', message: action.error.data.message })
}
return next(action)
}
import { isRejectedWithValue } from '@reduxjs/toolkit'
import { toast } from 'your-cool-library'
/**
* Log a warning and show a toast!
*/
export const rtkQueryErrorLogger = (api) => (next) => (action) => {
// RTK Query uses `createAsyncThunk` from redux-toolkit under the hood, so we're able to utilize these matchers!
if (isRejectedWithValue(action)) {
console.warn('We got a rejected action!')
toast.warn({ title: 'Async error!', message: action.error.data.message })
}
return next(action)
}