Sir*_*haa 5 apollo reactjs graphql next.js apollo-client
嗯,我有点矮胖。我会尽力尽可能清楚地解释我的问题。
我使用 Apollo 客户端来执行 GraphQL 查询。我也使用 NextJS。出于 SEO 原因,我有一个页面需要在服务器端呈现。
所以我有一个getProductFromSlug函数可以让我执行我的请求。
export const getProductFromSlug = async (slug: string) => {
try {
const { data, error } = await apolloClient.query<{
product: Product
}>({
query: GET_PRODUCT_BY_SLUG_QUERY,
variables: {
slug,
},
})
if (error) {
return { errors: [error.message] }
}
if (!('product' in data) || data.product === null) {
return { errors: ['Product with specified url not found'] }
}
return {
data,
}
} catch (error) {
// @ts-ignore
const formattedErrors: ApolloError = isApolloError(error)
? error.graphQLErrors.map((error) => error.message)
: [`Unhandled error : ${error}`]
return {
errors: formattedErrors,
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里是getServerSideProps向页面传递数据
export const getServerSideProps = async (
context: GetServerSidePropsContext
) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const requestData = await getProductFromSlug(context.params.slug as string)
return 'errors' in requestData
? { notFound: true, props: requestData }
: { props: requestData }
}
Run Code Online (Sandbox Code Playgroud)
问题是,当我从端点收到 HTTP 代码 500 时,SSR 崩溃,在 Vercel 上,它会导致无服务器崩溃错误。
错误:响应不成功:收到状态代码 500 生成页面时发生此错误。任何控制台日志都将显示在终端窗口中
如果需要,这是我的入口点(_app.tsx):
function MyApp(props: AppProps) {
return (
<ApolloProvider client={apolloClient}>
<RecoilRoot>
<RecoilNexus />
<AuthenticationFromStorage />
<Layout>
<props.Component {...props.pageProps} />
</Layout>
</RecoilRoot>
</ApolloProvider>
)
}
Run Code Online (Sandbox Code Playgroud)
您可以在这里看到我的 Apollo 客户端:https://gist.github.com/SirMishaa/d67e7229307b77b43a0b594d0c9e6943
yarn run dev(next dev -p 3005)的堆栈跟踪:
ServerError: Response not successful: Received status code 500
at Object.throwServerError (C:\Users\misha\Documents\dev\rekk-next\node_modules\@apollo\client\link\utils\utils.cjs:45:17)
at C:\Users\misha\Documents\dev\rekk-next\node_modules\@apollo\client\link\http\http.cjs:31:19
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
error - uncaughtException: ServerError: Response not successful: Received status code 500
error Command failed with exit code 1.
Run Code Online (Sandbox Code Playgroud)
注意: 在 try 和 catch 范围内尝试使用 console.log 后,它在 Next SSR 控制台中没有显示任何内容,因此由于某种原因没有捕获 Apollo 的内部错误。
我感谢您的帮助,谢谢!
更新
问题是,当出现错误时,PusherLink没有继续在链中执行。添加error和complete处理程序解决了问题。
forward(operation).subscribe({
next: (data) => {
...
this.subscribeToChannel(subscriptionChannel, observer)
},
// these two were missing
error: (error) => observer.error(error),
complete: () => observer.complete(),
})
Run Code Online (Sandbox Code Playgroud)
JIC,我还添加了一个缺失条件,作为参考的另一个链接的代码有
subscribeObservable.subscribe = (observerOrNext, onError, onComplete) => {
if (typeof(observerOrNext) == "function") {
prevSubscribe(observerOrNext, onError, onComplete)
} else {
prevSubscribe(observerOrNext)
}
Run Code Online (Sandbox Code Playgroud)
旧答案
catch 块内的代码可能会抛出错误,这就是问题所在。我不确定这个条件Array.isArray(apolloError),也许你的意思是Array.isArray(apolloError.graphQLErrors)
您可以尝试让该isApolloError实用程序变得更清晰一些,并从 TS 类型中获得一些提示。
forward(operation).subscribe({
next: (data) => {
...
this.subscribeToChannel(subscriptionChannel, observer)
},
// these two were missing
error: (error) => observer.error(error),
complete: () => observer.complete(),
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2107 次 |
| 最近记录: |