reduxjs / redux-toolkit

The official, opinionated, batteries-included toolset for efficient Redux development
https://redux-toolkit.js.org
MIT License
10.69k stars 1.16k forks source link

RTK Query - Setting a query to failed programatically #2685

Open Lukas-Kullmann opened 2 years ago

Lukas-Kullmann commented 2 years ago

In the docs, there is a section about streaming updates: https://redux-toolkit.js.org/rtk-query/usage/streaming-updates

However, there is no recommendation on how to handle errors for those updates. An example for an error in a streaming update is a malformed payload.

In our application, we would like to set the whole query into an error state if there is a streaming update. So for us it does not matter if the original query failed or if there was a problem with a streaming update. It would be great if there was a method to set the query into a failed state for this use case.

I played around a bit and noticed that I can just build and dispatch the rejected action manually. But that feels super weird. I would rather have a method that builds that action for me. Did I miss this functionality? What's the recommended way of handling errors for streaming updates?

Here's an example snippet on how I set the error:

async onCacheEntryAdded(
  arg,
  { updateCachedData, cacheDataLoaded, cacheEntryRemoved, dispatch, requestId }
) {
  const ws = new WebSocket('ws://localhost:8080')

  try {
    await cacheDataLoaded

    const listener = (event: MessageEvent) => {
      try {
        const data = JSON.parse(event.data)
        if (!isMessage(data) || data.channel !== arg) return

          updateCachedData((draft) => {
            draft.push(data)
          })
      } catch (error) {
        // example: JSON.parse failed

        dispatch({
          type: 'myApi/executeQuery/rejected',
          payload: error,
          meta: {
            requestId,
            rejectedWithValue: Boolean(error),
            requestStatus: 'rejected',
            aborted: false,
            condition: false,
            arg: {
              type: 'query',
              subscribe: true,
              subscriptionOptions: { pollingInterval: 0 },
              endpointName: 'endpointName',
              originalArgs: queryArg,
              queryCacheKey: `endpointName(${JSON.stringify(queryArg)})`,
            },
          },
          error: { message: 'Rejected' },
        });
      }
    }

    ws.addEventListener('message', listener)
  } catch {}

  await cacheEntryRemoved
  ws.close()
},
kans commented 1 year ago

Bumping for visibility. I have exactly this problem, but would prefer not to resort to stringly typing.

Edit: flipping the state back to "fulfilled" is just as ugly, since updateCachedData doesn't touch the status... The docs completely elide error handling within onCacheEntryAdded. It doesn't look like either the internal action (query) nor the associated types are exposed anywhere.

markerikson commented 1 year ago

We don't have a way to do this, and it's not a priority, but if someone would like to file a PR we can take a look!

tothdanielax commented 11 months ago

Is there an update on this? I'm in the exact same situation (stackoverflow) but can't make it work like @Lukas-Kullmann did. Could you provide an example that how we should handle errors with streaming logic?