graphql-codegen-apollo-next-ssr icon indicating copy to clipboard operation
graphql-codegen-apollo-next-ssr copied to clipboard

Errors returned by getServerPage() can't be serialized to JSON

Open mbrowne opened this issue 3 years ago • 4 comments

In getServerSideProps(), it's not safe to return the object returned by getServerPage as-is. This is because errors in res.props.error can't be serialized to JSON.

This might not be a bug, but it does mean that you have to do your own error handling in every getServerSideProps function rather than handling that when you're rendering your component, or in pages/_app.tsx to keep your code more DRY. And it's confusing, because I thought that a property named props would be something you could safely return as the page props without modification.

The issue can be reproduced most easily by faking a GraphQL error:

import { GraphQLError } from 'graphql'
...
export async function getServerSideProps(ctx: GetServerSidePropsContext) {
  ...
  res.props.error = [new GraphQLError('foo')]

This causes a next.js Server Error:

Error: Error serializing .error[0] returned from getServerSideProps in "/artists/[creatorId]/[lotId]". Reason: object ("[object Object]") cannot be serialized as JSON. Please only return JSON serializable data types.

It would be great if the generated code returned an error prop that can be properly stringified to JSON instead of returning the ApolloError or GraphqlErrors objects directly. Or alternatively maybe generate a function you can optionally use to do the conversion, something like this:

    if (res.props.error) {
        return ssrMyQuery.pagePropsForErrorPage(res)
    }

...which would grab the error message(s) and return a plain object, e.g.:

{
  props: {
    error: {
      message: 'GraphqlError: foo'
    }
  }
}

mbrowne avatar Jun 29 '21 16:06 mbrowne

ok, thanks for the idea, I will explore this option

correttojs avatar Jun 30 '21 06:06 correttojs

I just discovered that this is a non-issue when using babel-plugin-superjson-next, which handles JSON serialization of Error objects automatically (and also Date objects, etc). (See alos https://github.com/blitz-js/superjson#using-with-nextjs.) Obviously probably not everyone will want to use that plugin, but I suppose this should be an optional feature for those who are using it.

mbrowne avatar Jun 30 '21 19:06 mbrowne

@mbrowne How did you solve this? Does implementing the babel-plugin-superjson-next automatically solve this? I've implemented it but I'm seeing the same issues with errors automatically triggering an issue.

I would definitely agree that an error message in plain object form would be awesome

Inlustra avatar Sep 01 '21 16:09 Inlustra

@Inlustra Yes, babel-plugin-superjson-next automatically solves this, because it looks at the whole response and automatically serializes anything that needs it (including errors and dates).

mbrowne avatar Sep 01 '21 16:09 mbrowne