0
votes

I'm currently building an app which uses Apollo for my GraphQL API. As we know, GraphQL provides a type and non-nullable checking for some fields. Suppose that I want foo field to be a Int and it's non-nullable field, we can do this in the schema (or typedefs)

foo: Int!

Which generates this kind of error

"message": "Variable \"$input\" got invalid value \"foo\"; Expected type Int; Int cannot represent non 32-bit signed integer value: foo"\

However, let's just say that I want to customize the message to something like

"message": "Foo is wrong"

Is it possible to change the default error message? The non-nullable is technically possible if you check it in your resolvers, but I don't think it's possible for the types too.

1

1 Answers

0
votes

The only way to somewhat change the error messages thrown during the serialization or parsing of scalars is to provide custom implementations of those scalars. For example, you can copy the source code for your scalar of choice:

const { GraphQLScalarType } = require('graphql')
const inspect = require('graphql/jsutils/inspect').default

function serializeID(rawValue) {
  const value = serializeObject(rawValue);

  if (typeof value === 'string') {
    return value;
  }
  if (Number.isInteger(value)) {
    return String(value);
  }
  throw new TypeError(`ID cannot represent value: ${inspect(rawValue)}`);
}

function coerceID(value) {
  if (typeof value === 'string') {
    return value;
  }
  if (Number.isInteger(value)) {
    return value.toString();
  }
  throw new TypeError(`Oh no! ID cannot represent value: ${inspect(value)}`);
}

const ID = new GraphQLScalarType({
  name: 'ID',
  description:
    'The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `"4"`) or integer (such as `4`) input value will be accepted as an ID.',
  serialize: serializeID,
  parseValue: coerceID,
  parseLiteral(ast) {
    return ast.kind === Kind.STRING || ast.kind === Kind.INT
      ? ast.value
      : undefined;
  },
})

const resolvers = {
  ID,
  /* the rest of your resolvers */
}

Now the validation message will instead be:

Variable \"$id\" got invalid value true; Expected type ID; Oh no! ID cannot represent value: true

Changing the first part of the message is not possible, though.

That said, validation errors mean something has gone wrong with your code, either on the client side (when validating inputs) or on the server-side (when validating outputs). Users probably should not be exposed to these errors and should be shown some generic error message instead.