JS-DevTools / ono

Wrap errors without losing the original message, stack trace, or properties
https://jstools.dev/ono/
MIT License
106 stars 11 forks source link

Have a option to preserve stacktrace of inner errors, but keep only latest error message #11

Closed PizzaPartyInc closed 4 years ago

PizzaPartyInc commented 4 years ago

Hey!

I have a case in my API project when I want to catch an error from some 3-d party library/ies and re-throw an ono error with original error as an inner error.

Because 3-d library/ies can throw any kinds of errors and their messages are not always something we want to expose as an api response I want to show nicer errors for api consumers, while also logging information about inner errors.

For example:

  async getData(): Promise<DataDto> {
    try {
      // Anything that can throw exception, e.g.
      throw new Error("unable to get name property of undefined");
    } catch (e) {
      throw ono(e, 'Error occurred while retrieving data');
    }
  }

In case above I would later in application errors filter get an error with concatenated message (2 or more), something like "Error occurred while retrieving data\nunable to get name property of undefined".

I'm interested in using ono because it preserves the stack trace, and that stack trace will also have the "unable to get name property of undefined" message, meaning we can trace the error and see separation between inner errors when this error is logged, but I would not want to show all concatenated errors as an API error response.

Do you think it makes sense for ono to support some sort of option to not concatenate messages while still combining stack traces? Or my use-case is a bit unique? :)

I know I can use '\n' as a separator and extract the first message, but there is also a possibility that ono-thrown error will have an \n of it's own in message, and that would cut of the message :)

Thanks!

JamesMessinger commented 4 years ago

I like this idea! Totally makes sense.

I'm not sure what the best way to add that option is though, since ono doesn't have an options parameter. 🤔 We could do it as a global setting, but that seems ugly:

import ono from "ono";
ono.concatMessages = false;

There's also the Ono constructor, which allows you to create custom ono instances for custom error classes. We could add an options parameter to that constructor that allows you to customize the behavior of the ono instance. This is a bit more complicated than the "global setting" approach above, but it's cleaner.

import { Ono } from "ono";
ono = new Ono(Error, { concatMessages: false });

Perhaps there's a third option that I'm not thinking of right now.

PizzaPartyInc commented 4 years ago

I also see an option of exposing more than one error type, but I'm not sure how good of a solution it is from the standpoint of an npm package. e.g. you can have something like this:

import { ono, ohno } from 'ono';

throw ono(e, "message from 'e' will be concatenated to this one")
throw ohno(e, "message from 'e' will NOT be concatenated to this one")
JamesMessinger commented 4 years ago

This feature has been added in Ono 6.0.0.

See the documentation here.