Coder Social home page Coder Social logo

thebigredgeek / apollo-errors Goto Github PK

View Code? Open in Web Editor NEW
407.0 10.0 33.0 89 KB

Machine-readable custom errors for Apollostack's GraphQL server

License: MIT License

Makefile 8.20% JavaScript 50.31% TypeScript 41.49%
graphql apollo-client apollo-server apollostack-graphql-server

apollo-errors's Introduction

apollo-errors

Machine-readable custom errors for Apollostack's GraphQL server

NPM

CircleCI

Example from Apollo Day

Authentication and Error Handling in GraphQL

Installation and usage

Install the package:

npm install apollo-errors

Create some errors:

import { createError } from 'apollo-errors';

export const FooError = createError('FooError', {
  message: 'A foo error has occurred'
});

Hook up formatting:

import express from 'express';
import bodyParser from 'body-parser';
import { formatError } from 'apollo-errors';
import { graphqlExpress } from 'apollo-server-express';
import schema from './schema';

const app = express();

app.use('/graphql',
  bodyParser.json(),
  graphqlExpress({
    formatError,
    schema
  })
);

app.listen(8080)

Throw some errors:

import { FooError } from './errors';

const resolverThatThrowsError = (root, params, context) => {
  throw new FooError({
    data: {
      something: 'important'
    },
    internalData: {
      error: `The SQL server died.`
    }
  });
}

Witness glorious simplicity:

POST /graphql (200)

{
  "data": {},
  "errors": [
    {
      "message":"A foo error has occurred",
      "name":"FooError",
      "time_thrown":"2016-11-11T00:40:50.954Z",
      "data":{
        "something": "important"
      }
    }
  ]
}

The internalData property is meant for data you want to store on the error object (e.g. for logging), but not send out to your end users. You can utilize this data for logging purposes.

import { isInstance as isApolloErrorInstance, formatError as formatApolloError } from 'apollo-errors';

function formatError(error) {
  const { originalError } = error;
  if (isApolloErrorInstance(originalError)) {
    // log internalData to stdout but not include it in the formattedError
    console.log(JSON.stringify({
      type: `error`,
      data: originalError.data,
      internalData: originalError.internalData
    }));
  }
  return formatApolloError(error)
}

API

ApolloError ({ [time_thrown: String, data: Object, internalData: object, message: String ]})

Creates a new ApolloError object. Note that ApolloError in this context refers to an error class created and returned by createError documented below. Error can be initialized with a custom time_thrown ISODate (default is current ISODate), data object (which will be merged with data specified through createError, if it exists), internalData object (which will be merged with internalData specified trough createError) and message (which will override the message specified through createError).

createError(name, {message: String, [data: Object, internalData: object, options: Object]}): ApolloError

Creates and returns an error class with the given name and message, optionally initialized with the given data, internalData and options. data and internalData passed to createError will later be merged with any data passed to the constructor.

Options (default):

  • showPath (false): Preserve the GraphQLError path data.
  • showLocations (false): Preserve the GraphQLError locations data.

formatError (error, strict = false): ApolloError|Error|null

If the error is a known ApolloError, returns the serialized form of said error.

Otherwise, if strict is not truthy, returns the original error passed into formatError.

Otherwise, if strict is truthy, returns null.

isInstance (error): Boolean

Returns true if the error is an instance of an ApolloError. Otherwise, returns false

apollo-errors's People

Contributors

ch-andrewrhyne avatar iamdanthedev avatar lakhansamani avatar luisgrases avatar lxcid avatar n1ru4l avatar renovate-bot avatar skout90 avatar thebigredgeek avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

apollo-errors's Issues

Message not propagating in 1.7.1

Changes between versions 1.5.1 and 1.7.1 appear to have broken the message field propagation when using createError:

const myError = createError('BadError', { message: "This is bad"});
var theError = new myError();
console.log(theError.message)

output of message field is undefined....

Works great in 1.5.1, broken in 1.7.1

Handle GraphQLError

I'm working with apollo-server-express, and I've created a custom scalar:

const regex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@(([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{2,})$/i;

export default {
  name: 'EmailString',
  description: 'E-Mail addresses compliant to RFC 822.',
  parseValue: (value) => {
    if (typeof value !== 'string') {
      throw new TypeError('Invalid Email input value (string expected)');
    }
    if (!regex.test(value)) {
      throw new TypeError('Invalid Email input value');
    }
    return value;
  },
  serialize: value => value,
  parseLiteral: (ast) => {
    if (ast.kind !== Kind.STRING) {
      throw new TypeError('Invalid Email input value (string expected)');
    }
    if (!regex.test(ast.value)) {
      throw new TypeError('Invalid Email input value');
    }
    return ast.value;
  },
};

But when it throws the error, formatError doesn't parse it 'cause it's an GraphQLError:

if (!name || !isInstance(originalError)) return returnNull ? null : error;

name is evaluated to GraphQLError string, then the response it's like this:

{
  "errors": [
    {
      "message": "Variable \"$email\" got invalid value \"asd\".\nExpected type \"UEmail\", found \"asd\": Invalid Email input value",
      "locations": [
        {
          "line": 1,
          "column": 45
        }
      ]
    }
  ]
}

And not how I expected to be:

{
  "data": {
    "addEmail": null
  },
  "errors": [
    {
      "message": "Invalid Email input value",
      "name": "TypeError",
      "time_thrown": "2017-10-22T13:48:28.989Z",
      "data": {}
    }
  ]
}

createError fails with no second argument

The optional second argument is not really optional

apollo-errors/dist/index.js:87
  var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { message: 'An error has occurred', options: options };
                                                                                                                              ^
ReferenceError: options is not defined
var createError = exports.createError = function createError(name) {
  var data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { message: 'An error has occurred', options: options };

  var e = ApolloError.bind(null, name, data);
  return e;
};

formatError is not working for me

Things to note, I am using graphql-server-express version 0.6.0, and I have hooked up formatError to my graphqlExpress, it just doesn't seem to work.

I created a new error with

export const FetchError = createError('FetchError' , { message: 'blark' });

I used the error

// data is the message body from a node-fetch
throw new FetchError({ data });

and I receive the following from GraphQL

{
  "data": null,
  "errors": [
    {
      "message": "ApolloError: FetchError/::/2017-03-13T14:42:02.244Z/::/null/::/{\"errorGroup\":\"UNAUTHORIZED\",\"errorCode\":\"AUT_00011\",\"errorMessage\":\"Invalid session cookie\"}",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "installation"
      ]
    }
  ]
}

Am I missing something obvious, or did I find a bug?

How do you compare a thrown error to an ApolloError type?

If I set a shared list of known errors:

import { createError, formatError } from 'apollo-errors';

export const PermissionsError = createError('PermissionsError', {
  message: 'Invalid permissions, you must be logged in to do this.',
});
export const UsernameTakenError = createError('UsernameTakenError', {
  message: 'Sorry, that username is taken.',
});
export const EmailRegisteredError = createError('EmailRegisteredError', {
  message: 'That email is already registered.',
});

export const errorTypes = {
  PermissionsError,
  UsernameTakenError,
  EmailRegisteredError,
};

How do you compare a thrown error to it's bound function? None of these seem to work

new UsernameTakenError() instanceof errorTypes.UsernameTakenError; // true for any type, cant distinguish
new UsernameTakenError().isInstance; // true, cant distinguish

Simpliest way I found:

throw new UsernameTakenError("This is SomeCaughtError");
...
...
new errorTypes.UsernameTakenError().name === SomeCaughtError.name;

I feel like I'm missing something simple ๐Ÿ˜•

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Edited/Blocked

These updates have been manually edited so Renovate will no longer make changes. To discard all commits and start over, click on a checkbox.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

circleci
.circleci/config.yml
  • circleci/node 8
  • circleci/node 10
  • circleci/node 12
  • circleci/node 14
npm
package.json
  • assert ^2.0.0
  • extendable-error ^0.1.5
  • babel-cli 6.26.0
  • babel-core 6.26.3
  • babel-eslint 7.2.3
  • babel-preset-es2015 6.24.1
  • babel-register 6.26.0
  • chai 3.5.0
  • eslint 3.19.0
  • eslint-plugin-babel 3.3.0
  • mocha 3.5.3
  • rimraf 2.6.3
  • typescript 2.9.2

  • Check this box to trigger a request for Renovate to run again on this repository

Pattern for when user logs out?

I have setup my resolvers, one of which is:

export const UnauthorizedError = createError('UnauthorizedError', {
	message: 'You must login to do that'
});

  • I have a login page, which checks to see if a user is logged in (looking in apollo store).

  • If the user is logged in, the page will kick them into the "authenticated area" of the app.

  • When a user is inside the app, they can click a logout button. This logout mutation returns a promise. In the .then(), I re-route the user to the login page.

  • If I were to re-route them to /login prior to the .then(), they would just get kicked back into the auth area (apollo store still thinks they're logged in).

My problem:

  • The user clicks logout, mutation runs, server is aware the user is no longer logged in

  • My .then() hasn't re-routed the user, so all of the queries are re-running and throwing "UnauthorizedError: You must login to do that" whenever somebody logs out.

Is my only option to update the store with optimistic UI, and kick them back to login page? Or is there a different pattern to use with my errors/resolvers on the server?

Print query that caused the error

It would be good to know what query caused the error and what the variables wereโ€ฆ Maybe just in dev mode due to lots of data and possible password leaksโ€ฆ

Integration with apollo-server

Just wondering whether you'd tried to get the package working with apollo-server yet? We are using it within Serverless as a Lambda rather than using Express.

v2 API

Wondering if there are any features that people would like to see in V2?

Dynamic messages

Great work with this module!

There is one thing missing, though: I would like to have dynamic messages for my errors when possible. To make that happen, message option could be received as function.

As you don't expose ApolloError, things are harder they it should to increment your lib. Here is a work around I'm using to achieve it:

const createDynamicError = (name, opts = {}) => class CustomError {
  constructor (...args) {
    const config = typeof opts === 'string' || typeof opts === 'function'
      ? { message: opts }
      : opts

    if (typeof config.message === 'function') {
      config.message = config.message(...args)
    }

    return new (createError(name, config))(...args.slice(-1))
  }
}

You could then use it like so:

const UserNotFoundError = createCustomError('UserNotFoundError', {
  message: username => `User ${username} not found`
})

// Or, shurtcuted:
const UserNotFoundError = createCustomError('UserNotFoundError', username => `User ${username} not found`)

// And use it like that:
new UserNotFoundError('lucas')

// Or, with data as in the original createError:
new UserNotFoundError('lucas', { data: { foo: 'bar' } })

Hope it helps someone ;)

Global "show locations"

Hello,

Thank you for this great module. I want to use it but I need the following improvement.

I think formatError should take in argument showLocations in order to hide or show the locations and path of any error.
Actually, to my mind, the implementation where the error is created is not responsible for how the error must be formatted/displayed : this is the role of formatError function.

If you agree I can open a PR.

What do you think ?

Best,

Yoann

How to pass variables into the error message.

This is more of a question than it is an issue. Is there any way to pass a variable into the error message?

If I have the following error message:

throw new Error(
  `There was no user found with the username, ${username}.`
);

How can I get that username into the apollo-errors? Is there a way to pass it as an argument?

throw new err.IncorrectUsernameError(username);

Inside my error file that imports apollo-errors:

exports.IncorrectUsernameError = createError('IncorrectPasswordError', {
  message: `There was no user found with the username, ${username}.`,
});

Please let me know if there is some way to accomplish this.

Feature Proposal: `internalData` Property on ApolloError Constructor

It would be awesome if we could have an internalData property on the Error constructor.

The internalData object is intended to be for data that is not intended to be sent to the client.

Instead it should be used for sensitive data.

E.g. A third party HTTP call timed out and you want to give your user an unspecified error, but still collect some detail data in your server logs.

At the moment I am doing it like this:

import {
  isInstance as isApolloErrorInstance,
  createError as createApolloError,
  formatError as formatApolloError
} from "apollo-errors";

const UnexpectedError = createApolloError(`UnexpectedError`, {
  message: `An unexpected error occured.`
});

const logger = data => console.log(JSON.stringify(data));

const formatError = error => {
  const { originalError } = error;
  if (isApolloErrorInstance(originalError)) {
    // The internal data contains information that should never leave the server!
    const internalInformation = originalError.data.internal;
    // therefore we delete it
    delete originalError.data.internal;
    // but we still want to log the data
    logger({
      type: `error`,
      name: originalError.name,
      data: internalInformation
    });
    return formatApolloError(error);
  } else {
    logger({
      type: `error`,
      name: `UnexpectedError`,
      data: {
        error
      }
    });
    return formatApolloError(new UnexpectedError());
  }
};

This is what I am doing inside my resolver:

import { createError as createApolloError } from "apollo-errors";

const SomeApolloError = createApolloError(`SomeApolloError`, {
  message: `Something predictable happened.`
});

export async function resolver() {
  throw new SomeApolloError({
    data: {
      foo: `Some data for the client.`,
      internal: {
        foo: `Some data for the logs that should never leave the server`
      }
    }
  });
}

I think this is a pretty common scenario and would like to hear your thoughts about this.

Create V2.0 Branch

Seems like release 2.0 has been on hold for a little while now and important updates like #35 have not been implemented yet.

@thebigredgeek shall we create a v2 branch and start merging features like #35 ?

Not sure what the correct workflow should be for that.

Recomendation for better implamantation

Hi,

I Have just implemented a similar library.
And just now I found out that instead of all the serialize and deserialize with delimiter mechanism you use.
You can just get the custom error that way:

formatError: function (error) {
  const customError = error.originalError;
  // Add path locations etc'
  return customError
}

see more in the graphql source here

I did the same mistake, and I'm planning to change it since it much cleaner and correct.

Returned error empty message

I can't seem to figure out why the message I define as a parameter for createError is not being returned when instantiating a new error.
But when I instantiate the error with a message the message gets returned as expected.

E.g. the following error:

const { createError } = require('apollo-errors');

const InvalidCredentialsError = createError('InvalidCredentialsError', {
  message: 'The provided credentials are invalid.'
});

module.exports = { InvalidCredentialsError };

I instantiate the error as follows:

const valid = await bcrypt.compare(password, user.password);
    if (!valid) {
      throw new InvalidCredentialsError();
    }

The resulting response is this (notice the empty message):

{
  "data": null,
  "errors": [
    {
      "message": "",
      "name": "InvalidCredentialsError",
      "time_thrown": "2018-04-08T07:59:39.258Z",
      "data": {}
    }
  ]
}

But when I instantiate the error like so:

const valid = await bcrypt.compare(password, user.password);
    if (!valid) {
      throw new InvalidCredentialsError({ message: 'Testmessage' });
    }

I get the following (expected) response:

{
  "data": null,
  "errors": [
    {
      "message": "Testmessage",
      "name": "InvalidCredentialsError",
      "time_thrown": "2018-04-08T08:00:40.677Z",
      "data": {}
    }
  ]
}

Not sure if it matters but the formatting options I set up as follows:

const { formatError } = require('apollo-errors');
const { GraphQLServer, Options } = require('graphql-yoga');
const { Prisma } = require('prisma-binding');
const { makeExecutableSchema } = require('graphql-tools');
const { importSchema } = require('graphql-import');
const resolvers = require('./resolvers');
const directiveResolvers = require('./directiveResolvers');

const schema = makeExecutableSchema({
  typeDefs: importSchema('./src/schema.graphql'),
  resolvers,
  directiveResolvers
});

const options = {
  formatError
};

const server = new GraphQLServer({
  schema,
  context: req => ({
    ...req,
    db: new Prisma({
      typeDefs: 'src/generated/prisma.graphql',
      endpoint: process.env.PRISMA_ENDPOINT,
      secret: process.env.PRISMA_SECRET,
      debug: true
    })
  })
});

server.start(options, () => console.log('Server is running on http://localhost:4000'));

Any guidance on how to fix this would be greatly appreciated.

message as an object

would be helpful to define errors with message objects. (that can carry more static info regarding the error like severity)

I would like to make a PR changing the current type of message to union of string and object

please let me know your opinion

Catching errors on the client

Where are query errors supposed to be caught on the client?

I throw a NotFoundError on the server if an item can't be found. The error info can be accessed in props.data.error, but it still results in an uncaught exception.

I might be missing something fairly simple, but the apollo docs are pretty light when it comes to error handling!

es6-error v4.1.0 breaks formatError

Thanks for your library. Its a great little helper.

in formatError function, with es6-error v4.0.6..
!name false
!isInstance(originalError) false

in formatError function, with es6-error v4.1.0..
!name false
!isInstance(originalError) true

Which prevents the serialization of the new merged message and just returns the original message without any data, processing of location/path options etc.

Fixing es6-error at 4.0.6 in project's package.json fixes this as a workaround.

GraphQL response is always null

I have a mutation to create an admin for my system:

mutation {
  createAdmin(
    name:"Test"
    phoneNumber:"8758"
    password:"12345"
  ) {
    _id
    createdAt
    updatedAt
  }
}

The mutation definition is like this:

const { UnknownError } = require('../../../helpers/errors')

const createAdmin = async (payload) => {
  try {
    const { error, value } = Joi.validate(payload, adminReqSchema)
    if (error) {
      throw new UnknownError({
        data: {
          reason: 'Schema validation error'
        }
      })
    }

    const admin = await new Admin({ name: value.name, phoneNumber: value.phoneNumber }).save()
    await new Auth({ userId: admin._id, role: 'admin', password: value.password }).save()

    return admin
  } catch (err) {
    console.log(err)
  }
}

I've defined my error here:

const { createError } = require('apollo-errors')

const UnknownError = createError('UnknownError', {
  message: 'An unknown error has occured'
})

module.exports = { UnknownError }

The response is get is always:

{
  "data": {
    "createAdmin": null
  }
}

EDIT: I've narrowed down this problem to the fact that I'm using async/await in my mutation functions and handling errors using try/catch blocks. I'd like to know the right way to use apollo-errors with async/await and try/catch blocks.

Handling errors on the client (react-apollo)

I've managed to set up this awesome package without trouble (I get the expected JSON output in my requests) but I'm not sure what to do from there.

My issue is that when I throw an error inside a mutation handled by react-apollo's graphql HoC, the error object returned by the promise doesn't contain the custom error properties defined on the server, only the message.

Am I doing something wrong? How are you supposed to catch custom errors on the client?

showPath option is not doing anything

showPath (false): Preserve the GraphQLError path data.

createError('SomeError', {
    message: 'Some error message.',
    options: {
        showLocations: false,
        showPath: true,
    },
});

Expected Behaviour
It shows the path in the GraphQL result.

Actual Behaviour
It is not showing the path, only if I enable showLocations too, which I don't want.

Typescript support

I'm hoping I'll have time to work on this soon, but what are your thoughts on adding Typescript support versus a complete rewrite in Typescript?

Where to add to GraphQL Yoga ?

Currently starting my server like so

const server = new GraphQLServer({
  typeDefs: this.typeDefs,
  resolvers: shieldedResolvers as any
});

which works great. So now I want to add the formatErros into the mix. Although I am unsure what it is..

These are the props that I have that are taken from the contructor.

constructor(props: Props);

export interface Props {
    directiveResolvers?: IDirectiveResolvers<any, any>;
    schemaDirectives?: {
        [name: string]: typeof SchemaDirectiveVisitor;
    };
    typeDefs?: ITypeDefinitions;
    resolvers?: IResolvers;
    resolverValidationOptions?: IResolverValidationOptions;
    schema?: GraphQLSchema;
    context?: Context | ContextCallback;
    mocks?: IMocks;
    middlewares?: IFieldMiddleware[];
}

Of course its not typeDefs, Resolvers, I did try middleware but it didn't work.

Anyone have any ideas ?

Reasoning behind the two-step error pattern?

The "normal" way to use this package is:

import { createError } from 'apollo-errors';

const FooError = createError('FooError', { message: 'A foo error has occurred' });

throw new FooError({ data: { something: 'important' } });

However, that seems a bit cumbersome to me. Is there a reason why the API doesn't look something like this instead?

import { ApolloError } from 'apollo-errors';

throw new ApolloError({ name: 'FooError', message: 'A foo error has occurred', data: { ... } });

Spec compliant error

Recently, GraphQL Response Specification got updated with a suggestion to place custom data in error in the extensions object. The spec can be found here https://github.com/facebook/graphql/blob/master/spec/Section%207%20--%20Response.md

An excerpt of the relevant section:

GraphQL services may provide an additional entry to errors with key extensions. This entry, if set, must have a map as its value. This entry is reserved for implementors to add additional information to errors however they see fit, and there are no additional restrictions on its contents.

{
  "errors": [
    {
      "message": "Name for character with ID 1002 could not be fetched.",
      "locations": [ { "line": 6, "column": 7 } ],
      "path": [ "hero", "heroFriends", 1, "name" ],
      "extensions": {
        "code": "CAN_NOT_FETCH_BY_ID",
        "timestamp": "Fri Feb 9 14:33:09 UTC 2018"
      }
    }
  ]
}

Working with Apollo Server 2.0

How would I use apollo-errors with Apollo Server 2.0? Example:

const { ApolloServer, gql } = require('apollo-server');

// Construct a schema, using GraphQL schema language
const typeDefs = gql`
  type Query {
    announcement: String
  }
`;

// Provide resolver functions for your schema fields
const resolvers = {
  Query: {
    announcement: () =>
      `Say hello to the new Apollo Server! A production ready GraphQL server with an incredible getting started experience.`
  }
};

const server = new ApolloServer({ typeDefs, resolvers });

server.listen().then(({ url }) => {
  console.log(`๐Ÿš€ Server ready at ${url}`);
});

Data values as array of object instead of object

If I put the data value as an object like your example

import { FooError } from './errors';

const resolverThatThrowsError = (root, params, context) => {
  throw new FooError({
    data: {
      something: 'important'
    }
  });
}

That will throwing something like this.

{
  "data": {},
  "errors": [
    {
      "message":"A foo error has occurred",
      "name":"FooError",
      "time_thrown":"2016-11-11T00:40:50.954Z",
      "data":{
        "something": "important"
      }
    }
  ]
}

But, if I put my data as an array of object.

import { FooError } from './errors';

const resolverThatThrowsError = (root, params, context) => {
  throw new FooError({
    data: [{
		something: 'important'
	}, {
		something: 'very important'
	}]
  });
}

Why it's throwing the data as object, not an array of object?

{
  "data": {},
  "errors": [
    {
      "message":"A foo error has occurred",
      "name":"FooError",
      "time_thrown":"2016-11-11T00:40:50.954Z",
      "data": {
		 "0": {
	        "something": "important"
	      },
		"1": {
	        "something": "very important"
	      }
      }
    }
  ]
}

I need my data to be an array of object, is that possible?

losing stack trace, anyway to retain it ?

Hi,

I am throwing a number of custom errors further up my project and these I generally would log before throwing, these are standard custom errors that inherit from the Error object in nodejs.

When I arrive at my resolver, I generally capture the error and throw an "apollo errors" Error but I lose the stack trace, the stack trace only has the entry of where I threw the new apollo error but nothing before it.

Do you know of a good solution or workaround ? I mean I could log the error before throwing the new apollo error but it would be great if it retained the stack trace

Here is what I am doing

  } catch (err) {
        switch (err.constructor) {
          case HttpBadRequestError:
            throw new BadRequestError()

          default:
            throw new InternalError()
        }
      }

The one above that is most important is the InternalError, this basically means it is an uncaught error.

here is my definition

import { createError } from 'apollo-errors'

export const InternalError = createError('InternalError', {
  message: 'An internal error has occurred'
})

As I say, throw the error here now removes all stacktrace from the previous error so all I know is that the code in the resolver threw an error but I have no reference to anything else.

I did try using longjohn - a node module for including longer stack traces, but I don't think this is the problem.

Anybody managed to work around this ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.