Here I have a resolver for coupon code redemption. It should throw an error when the code doesn't exist or has a claim. Apollo server provides a few errors we can use to communicate errors to a client.
import { OperationContext } from "../../../graphql/OperationContext"
import { assertUserId } from "../../../auth/assertUserId"
import * as appSumoCodesDb from "../db"
import { UserInputError } from "apollo-server-lambda"
interface Input {
  code: string
}
export const redeemAppSumoCode = async (
  _: any,
  { input: { code } }: { input: Input },
  context: OperationContext
) => {
  const userId = assertUserId(context)
  const appSumoCode = await appSumoCodesDb.getAppSumoCodeById(code)
  if (!appSumoCode || appSumoCode.userId !== userId) {
    throw new UserInputError("Invalid code")
  }
  // ...
}
We can go to the source code and see that they all extend ApolloErro. So if we need a custom error, we can copy one of the classes from here and change the name with a code.
export class UserInputError extends ApolloError {
  constructor(message: string, extensions?: Record<string, any>) {
    super(message, "BAD_USER_INPUT", extensions)
    Object.defineProperty(this, "name", { value: "UserInputError" })
  }
}
Apollo Server always responds with 200, but if API threw an error, we'll receive errors with a response. I formatted the error to include only the message and extensions. If we want to provide extra information, we can add an object as a second parameter to ApolloError, and it will appear in the extensions object. To omit stack trace from extension, set NODE_ENV to production.
const server = new ApolloServer({
  typeDefs,
  resolvers,
  // ...
  formatError: ({ message, extensions }) => {
    return {
      message,
      extensions,
    }
  },
})
I run Apollo Server on AWS Lambda and use Sentry for error monitoring. Don't forget to pass ignoreSentryErrors, otherwise, your lambda will crash if you reach Sentry's quote.
exports.handler = Sentry.AWSLambda.wrapHandler(server.createHandler(), {
  ignoreSentryErrors: true,
})
 
 
              
 
    
Top comments (0)