【问题标题】:How to handle error format in Redux-toolkit rtk-query graphql application如何在 Redux-toolkit rtk-query graphql 应用程序中处理错误格式
【发布时间】:2022-08-02 19:29:57
【问题描述】:

我正在开发一个基于 redux-toolkit rtk-query 和 graphql 的应用程序。 我使用 graphql-codegen 从 graphql 模式开始生成 reducer,一切都按预期工作。

现在我有一个处理错误的问题。我是否了解 redux-toolkit 会以这样的特定格式引发自定义错误

{
  name: \"Error\",
  message: \"System error\",
  stack:
    \'Error: System error: {\"response\":{\"errors\":[{\"message\":\"System error\",\"locations\":[{\"line\":3,\"column\":3}],\"path\":[\"completaAttivita\"],\"extensions\":{\"errorCode\":505,\"classification\":\"VALIDATION\",\"errorMessage\":\"Messaggio di errore\",\"verboseErrorMessage\":\"it.cmrc.sid.backend.exception.CustomException: I riferimenti contabili non sono più validi\",\"causedBy\":\"No Cause!\"}}],\"data\":{\"completaAttivita\":null},\"status\":200,\"headers\":{\"map\":{\"content-length\":\"398\",\"content-type\":\"application/json\"}}},\"request\":{\"query\":\"\\\\n    mutation completaAttivita($taskName: TipoAttivita, $taskId: String, $determinaId: BigInteger, $revisione: Boolean, $nota: NotaInputInput, $avanzaStatoDetermina: Boolean, $attribuzioniOrizzontali: AttribuzioniOrizzontaliInputInput, $firmaInput: FirmaInputInput, $roles: [String]) {\\\\n  completaAttivita(\\\\n    taskName: $taskName\\\\n    taskId: $taskId\\\\n    determinaId: $determinaId\\\\n    revisione: $revisione\\\\n    nota: $nota\\\\n    avanzaStatoDetermina: $avanzaStatoDetermina\\\\n    attribuzioniOrizzontali: $attribuzioniOrizzontali\\\\n    firmaInput: $firmaInput\\\\n    roles: $roles\\\\n  ) {\\\\n    id\\\\n  }\\\\n}\\\\n    \",\"variables\":{\"taskId\":\"24ac495b-46ca-42f4-9be2-fd92f0398114\",\"determinaId\":1342,\"taskName\":\"firmaDirigente\",\"firmaInput\":{\"username\":\"fdfs\",\"password\":\"fdsf\",\"otp\":\"fdsdf\"}}}}\\n    at eval (webpack-internal:///../../node_modules/graphql-request/dist/index.js:354:31)\\n    at step (webpack-internal:///../../node_modules/graphql-request/dist/index.js:63:23)\\n    at Object.eval [as next] (webpack-internal:///../../node_modules/graphql-request/dist/index.js:44:53)\\n    at fulfilled (webpack-internal:///../../node_modules/graphql-request/dist/index.js:35:58)\'
};

但是我的 graphql 端点返回了这个

{
  errors: [
    {
      message: \"System error\",
      locations: [{ line: 3, column: 3 }],
      path: [\"completaAttivita\"],
      extensions: {
        errorCode: 505,
        classification: \"VALIDATION\",
        errorMessage: \"Messaggio di errore\",
        verboseErrorMessage:
          \"it.cmrc.sid.backend.exception.CustomException: Messaggio di errore\",
        causedBy: \"No Cause!\"
      }
    }
  ],
  data: { completaAttivita: null }
};

使用 rtk-query 和自动生成的客户端,我无法访问服务器的完整响应。 我需要在异常对象中提取错误消息。

从 redix-toolkit 文档中,我了解到我需要捕获错误并从createAsyncThunk 调用rejectwithvalue(),但我不知道这样做。

这里是基础 api 对象

import { createApi } from \'@reduxjs/toolkit/query/react\';
import { graphqlRequestBaseQuery } from \'./base-request\';
import { GraphQLClient } from \'graphql-request\';
import { getSession } from \'next-auth/react\';

export const client = new GraphQLClient(
  `${process.env.NEXT_PUBLIC_API_URL}/graphql`,
  {
    credentials: \'same-origin\',
    headers: {
      Accept: \'application/json\'
    }
  }
);

export const api = createApi({
  baseQuery: graphqlRequestBaseQuery({
    client,
    prepareHeaders: async (headers, { getState }) => {
      const session = await getSession();
      if (session) {
        headers.set(\'Authorization\', `Bearer ${session?.access_token}`);
      }

      return headers;
    }
  }),
  endpoints: () => ({}),
  refetchOnMountOrArgChange: true
});

标签: reactjs graphql redux-thunk redux-toolkit rtk-query


【解决方案1】:

您始终可以在 baseQuery 周围编写一个包装器来重新格式化它:

const originalBaseQuery = graphqlRequestBaseQuery(...)

const wrappedBaseQuery = async (...args) => {
  const result = await originalBaseQuery(...args);
  if (result.error) {
    // modify `result.error` here however you want
  }
  return result
}

您可能还需要为此尝试..catch:

const originalBaseQuery = graphqlRequestBaseQuery(...)

const wrappedBaseQuery = async (...args) => {
  try {
    return await originalBaseQuery(...args);
  } catch (e) {
    // modify your error here
     return { error: e.foo.bar }
  }
}

我想这只是在我写graphqlRequestBaseQuery 的时候溜走了,到目前为止还没有人问过这个问题。如果您发现了一个很好的处理模式,那么对graphqlRequestBaseQuery 的拉取请求也将非常受欢迎。

【讨论】:

  • 感谢您的答复。不幸的是,你的建议不能解决我的问题。无论如何,我将提交一个拉取请求以自定义 graphqlRequestBaseQuery 中的错误对象。
【解决方案2】:

感谢@phry 合并我的解决方案。

@rtk-query/graphql-request-base-query(版本 > 2.1.0)引入了一个新配置来处理错误格式。这里做一个小解释。

类型化


graphqlRequestBaseQuery<CustomErrorFormat>

自定义错误处理程序

...
   customErrors: (props: ClientError) => CustomErrorFormat
...

完整示例https://codesandbox.io/s/headless-microservice-uzujqb?file=/src/App.tsx

import { createApi } from '@reduxjs/toolkit/query/react';
import { graphqlRequestBaseQuery } from '@rtk-query/graphql-request-base-query';
import { ClientError, GraphQLClient } from 'graphql-request';
import { getSession } from 'next-auth/react';

export const client = new GraphQLClient(
  `${process.env.NEXT_PUBLIC_API_URL}/graphql`,
  {
    credentials: 'same-origin',
    headers: {
      Accept: 'application/json'
    }
  }
);

export const api = createApi({
  baseQuery: graphqlRequestBaseQuery<
    Partial<ClientError & { errorCode: number }>
  >({
    client,
    prepareHeaders: async (headers, { getState }) => {
      const session = await getSession();
      if (session) {
        headers.set('Authorization', `Bearer ${session?.access_token}`);
      }

      return headers;
    },
    customErrors: ({ name, stack, response }) => {
      const { errorMessage = '', errorCode = 500 } = response?.errors?.length
        ? response?.errors[0]?.extensions
        : {};

      return {
        name,
        message: errorMessage,
        errorCode,
        stack
      };
    }
  }),
  endpoints: () => ({}),
  refetchOnMountOrArgChange: true
});

【讨论】:

    猜你喜欢
    • 2022-11-19
    • 2023-01-15
    • 2022-10-07
    • 2021-09-10
    • 2022-11-24
    • 2022-08-18
    • 2021-11-06
    • 2021-11-18
    • 1970-01-01
    相关资源
    最近更新 更多