Well, I'm a little dumpy. I will try to explain my problem as clearly as possible.
I use Apollo client to do my GraphQL queries. I also use NextJS. I have a page that needs to be rendered on the server side for SEO reasons.
So I have a getProductFromSlug
function that allows me to execute my request.
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,
}
}
}
Here's getServerSideProps
to pass data to page
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 }
}
The problem is that when I have a HTTP code 500 from the endpoint, the SSR is crashing and on Vercel, it's causing a serverless crash error.
Error: Response not successful: Received status code 500 This error happened while generating the page. Any console logs will be displayed in the terminal window
If needed, here's my entry point (_app.tsx):
function MyApp(props: AppProps) {
return (
<ApolloProvider client={apolloClient}>
<RecoilRoot>
<RecoilNexus />
<AuthenticationFromStorage />
<Layout>
<props.Component {...props.pageProps} />
</Layout>
</RecoilRoot>
</ApolloProvider>
)
}
You can see my Apollo Client here : https://gist.github.com/SirMishaa/d67e7229307b77b43a0b594d0c9e6943
Stack trace of 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.
NOTE : After some try with console.log in try and catch scope, it shows nothing in the Next SSR console, so the internal error of Apollo is not caught for some reason.
I appreciate your help, thank you!
UPDATE
The issue was that PusherLink was not continuing the execution in the chain when there was an error. Adding the error
and complete
handlers solved the problem.
forward(operation).subscribe({
next: (data) => {
...
this.subscribeToChannel(subscriptionChannel, observer)
},
// these two were missing
error: (error) => observer.error(error),
complete: () => observer.complete(),
})
JIC, I also added a missing condition the code from the other link taken as a reference has
subscribeObservable.subscribe = (observerOrNext, onError, onComplete) => {
if (typeof(observerOrNext) == "function") {
prevSubscribe(observerOrNext, onError, onComplete)
} else {
prevSubscribe(observerOrNext)
}
OLD ANSWER
Your code inside the catch block could be throwing an error, and that's what is breaking. I'm unsure about this condition Array.isArray(apolloError)
, maybe you meant Array.isArray(apolloError.graphQLErrors)
You could try the isApolloError
utility to be a little more clear and get some hints from TS types.
import { isApolloError } from '@apollo/client';
...
const formattedErrors = isApolloError(e)
? e.graphQLErrors.map(error => error.message)
: [`Unhandled error : ${e}`];
return {
errors: formattedErrors,
};