65

A command tool to generate error classes for your Apollo GraphQL server/client!

 5 years ago
source link: https://www.tuicool.com/articles/hit/jieimiU
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

7Bvme2V.png!web

Apollo Prophecy

:pager:

You shall fail... successfully

Command tool to generate errors files for your Appolo Server and Client

:pager: Features

  • Generate Server-side throwable errors in your resolvers like throw new NotAProphetError()
  • Expose machine readable graphql errors through your api documentation
  • Generate Client-side Apollo errors consumable like errorHere(error).isNotAProphetError ?

:clipboard: Table of Contents

  • Installation
  • Usage
    • Server Side
    • Client Side
  • Todo
  • Contribute
  • Test and Miscellaneous

Installation

First, install apollo-prophecy globaly

npm install -g apollo-prophecy

Usage

Usage: apollo-prophecy [command]

Commands:
  apollo-prophecy generate <json file> [--out]
  apollo-prophecy ask <graphql endpoint> [--field] [--out]

Options:
  -h, --help     Show help                                             [boolean]
  -v, --version  Display version number                                [boolean]

Server

generate command

This command creates the Error.ts file from a JSON input file, using --out param you can change the name and location. Input file should at least contains the keys message and code

apollo-prophecy generate errors.json

For example given the following errors.json as input:

{
  "AuthenticationRequiredError": {
    "message": "You must be logged in to do this",
    "code": "AUTH_REQUIRED"
  },
  "UserNotFoundError": {
    "message": "No user found",
    "code": "USER_NOT_FOUND"
  },
}

Apollo Prophecy will generate the following Errors.ts

export class AuthenticationRequiredError extends ProphecyError {
  constructor(properties?: Record<string, any>) {
    super("AuthenticationRequiredError", "You must be logged in to do this","AUTH_REQUIRED", properties);
  }
}
  
export class UserNotFoundError extends ProphecyError {
  constructor(properties?: Record<string, any>) {
    super("UserNotFoundError", "No user found", "USER_NOT_FOUND", properties);
  }
}

Now you can use it the following way throw new UserNotFoundError() in your resolvers.

apollo-prophecy also exposes a definitions object and a graphql type definition named PropheticError so that you can expose all your errors descriptions through resolvers,go see Client.

...
export const definitions = [{
    "name": "AuthenticationRequiredError"
    "message": "You must be logged in to do this",
    "extensions": {
      "code": "AUTH_REQUIRED"
    }
  }, {
    "name": "UserNotFoundError"
    "message": "No user found",
    "extensions": {
      "code": "USER_NOT_FOUND"
    }
  }
}];

export const errorType = `
  type PropheticErrorExtensions {
    code: String
  }

  type PropheticError {
    message: String?
    extensions: PropheticErrorExtensions
  }
`;
...

Client

ask command

This command queries the errors field on a graphql endpoint and creates an Errors.ts file containing helpers for all the errors exposed through the server api documentation.

apollo-prophecy ask http://localhost:3000/graphql

Usage

In order to easily handle erros with Apollo-Client , the generated Errors.ts exposes two methods errorHere and isThis , both takes one paramater of type ApolloError or GraphQLError .

errorHere() function

errorHere returns an object that has a property for each errors. You can perform a simple boolean check on the error argument by calling the approiate key .

import { errorHere } from `./_generated/Errors.ts`;

...(error) => {
  if(errorHere(error).isUserNotFoundError){
    // Do something
  } else if(errorHere(error).isNotAProphetError){
    // Do something else
  }
}

isThis() function

isThis returns an object that has a handler method for each errors. It perfoms a simple check on the error argument, if the it succeed the corresponding handler is called otherwise nothing happens.

Note: Handlers can return a values.

import { isThis } from `./_generated/Errors.ts`;

...(error) => {
  isThis(error)
  .UserNotFoundError(() => ...)
  .NotAProphetError(() => ...)
  .handle()
}

React example:

import { isThis } from `./_generated/Errors.ts`;

...(error) => {
  return <p style={{color: '#FF495C'}}>
    {
      isThis(error)
      .UserNotFoundError(() => <span>Could not find a user with tha name</span>)
      .NotAProphetError(() => <span>Only Prophets can perfom this kind of actions...</span>)
      .handle();
    }
  <p style={{color: '#FF495C'}}>
}

Contributing

:fist: Grab an issue -> :fork_and_knife: fork **develop** -> :man:‍:computer: Code -> Test -> :envelope_with_arrow: Pull Request -> :boom: :boom: :boom:

TODO

Running tests locally:

npm test
yarn test

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK