UNPKG

@tipe/graphql-apollo-errors

Version:

A small library to handle graphql and apollo errors in a better way

160 lines (136 loc) 6.33 kB
# graphql-apollo-errors A small library to handle graphql and apollo errors in a better way This library is fully tested with 100% coverage [![CircleCI](https://circleci.com/gh/GiladShoham/graphql-apollo-errors/tree/master.svg?style=svg)](https://circleci.com/gh/GiladShoham/graphql-apollo-errors/tree/master) [![Coverage Status](https://coveralls.io/repos/github/GiladShoham/graphql-apollo-errors/badge.svg?branch=master)](https://coveralls.io/github/GiladShoham/graphql-apollo-errors?branch=master) [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=CYFBUDM226DLS&lc=IL&item_name=graphql%2dapollo%2derrors&item_number=github%2dnpm&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted) ## Initiative Error handling requires few core features to be useful: * Ability to customize error in well defined structure cross app * Ability to hook the error bubbling (In order to log or store the errors somewhere) * Ability to send the error to the client while sending all the relevant information yet keeping all the sensitive information only on the server Looking around I found only 2 libraries dealing with errors in graphql and apollo - [graphql-errors](https://github.com/kadirahq/graphql-errors) , [apollo-errors](https://github.com/thebigredgeek/apollo-errors). Both libraries are great start, but they are not powerful enough for my opinion, therefore I decided to write my own error handler. Talking with some friends, I understand I'm not alone with this need, so I created this library as open source. ## Usage (Look in the spec files to understand more) Configure apollo error formatting ```js import express from 'express'; import bodyParser from 'body-parser'; import { formatErrorGenerator } from 'graphql-apollo-errors'; import schema from './schema'; // You can use what ever you want, this is just an example var logger = require('minilog')('errors-logger'); const formatErrorOptions = { logger, publicDataPath: 'public', // Only data under this path in the data object will be sent to the client (path parts should be separated by . - some.public.path) showLocations: true, // whether to add the graphql locations to the final error (default false) showPath: true, // whether to add the graphql path to the final error (default false) hideSensitiveData: false, // whether to remove the data object from internal server errors (default true) hooks: { // This run on the error you really throw from your code (not the graphql error - it means not with path and locations) onOriginalError: (originalError) => {logger.info(originalError.message)}, // This will run on the processed error, which means after we convert it to boom error if needed // and after we added the path and location (if requested) // If the error is not a boom error, this error won't include the original message but general internal server error message // This will run before we take only the payload and the public path of data onProcessedError: (processedError) => {logger.info(processedError.message)}, // This will run on the final error, it will only contains the output.payload, and if you configured the publicDataPath // it will only contain this data under the data object // If the error is internal error this error will be a wrapped internal error which not contains the sensitive details // This is the error which will be sent to the client onFinalError: (finalError) => {logger.info(finalError.message)}, } }; const formatError = formatErrorGenerator(formatErrorOptions); const app = express(); app.use('/graphql', bodyParser.json(), graphqlExpress({ formatError, schema }) ); app.listen(8080) ``` Init SevenBoom object The defalut args for SevenBoom are ```js const defaultArgsDef = [ { name : 'errorCode', order: 1 }, { name : 'timeThrown', order: 2, default: null }, { name : 'guid', order: 3, default: null } ]; ``` If you want you can change it using the initSevenBoom function: ```js import { initSevenBoom } from 'graphql-apollo-errors'; const customArgsDefs = [ { name : 'errorCode', order: 1 } ]; initSevenBoom(customArgsDefs); ``` Use SevenBoom to create your custom error and throw it. ```js import { SevenBoom } from 'graphql-apollo-errors'; // A resolver which throws error const getUserByIdResolver = (root, { userId }, context) => { UserService.getUserById(userId) .then((user) => { if (user) return user; const errorMessage = `User with id: ${userId} not found`; const errorData = { userId }; const errorName = 'USER_NOT_FOUND'; const err = SevenBoom.notFound(errorMessage, errorData, errorName); throw(err); } } ``` Enjoy your shiny error on the client ```js { "data": {}, "errors": [ { statusCode: '404', error: 'Not Found', message: 'User with id: 123 not found.', code: 'USER_NOT_FOUND', timeThrown: "2017-01-16T21:25:58.536Z", guid: 'b6c44655-0aae-486a-8d28-533db6c6c343', data: { userId: '123' } } ] } ``` ## Upgrade from v1.*.* There is a lot of changes from v1. (In the implementation, which leads to API changes) * onStoredError hook is no longer exist (actually the onOriginalError result is the same as the onStoredError before) * You should not use the throwError any more (it was deleted), you can use the native throw now. ## How does it work In general this library contain 2 parts: 1. [SevenBoom](https://github.com/GiladShoham/seven-boom) - A small library i wrote to create customize errors 2. format error function - which knows to fetch the real error, hide sensitive server data, add some hooks points and configuration, and pass it to the client. ## License MIT - Do what ever you want ## Contribute I'm open to hear any feedback - new ideas, bugs, needs. Feel free to open issues / PR ## Support on PayPal Hey dude! Help me out for a couple of :beers:! [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=CYFBUDM226DLS&lc=IL&item_name=graphql%2dapollo%2derrors&item_number=github%2dnpm&currency_code=USD&bn=PP%2dDonationsBF%3abtn_donateCC_LG%2egif%3aNonHosted)