TritonDataCenter / node-verror

Rich JavaScript errors
MIT License
1.18k stars 61 forks source link

Expose "jse_shortmsg" publicly #52

Closed chudley closed 6 years ago

chudley commented 6 years ago

When receiving a complex VError that potentially has many MultiErrors as causes, it would be nice to be able to pick apart this error and display it for human consumption. As it is, the "message" property contains details of the cause, and if it's a MultiError it only prints the first (e.g. "first of 1 error: ..."), and there's no public method of getting just the top-level error message that doesn't refer to these MultiErrors.

For example, given the following VError:

> var component0 = new VError.MultiError([ new VError('problem0'), new VError('problem1'), new VError('problem2') ], 'something bad happened with component0');
> var component1 = new VError.MultiError([ new VError('problem0'), new VError('problem1'), new VError('problem2') ], 'something bad happened with component1');
> var e = new VError(new VError.MultiError([ component0, component1 ]), 'unable to do thing because of problems');
> e.message
'unable to do thing because of problems: first of 2 errors: first of 3 errors: problem0'

I want to computationally explore and print this VError object in my command line utility to be able to iterate over these nested errors with VError.errorFromList and only display jse_shortmsg for readability.

This is possible by reaching into the VError and using the jse_shortmsg directly, but given that it's not documented I'd prefer not to rely on it. If this was a public property, I could rely on it existing and build an iterator over these nested VErrors to provide human friendly feedback. The end goal I have in mind here is having the "cmdln" library do this iteration/printing to display all error messages.

chudley commented 6 years ago

I realise now that this is pretty much what WError is for. WError is intended to hide the underlying errors from the top error, but they still exist as causes that can be explored.

A rough example similar to the one I initially provided:

var VError = require('verror');

var component0 = new VError.WError(new VError.MultiError([
    new VError('problem0'),
    new VError('problem1'),
    new VError('problem2')
]), 'something bad happened with component0');

var component1 = new VError.WError(new VError.MultiError([
    new VError('problem0'),
    new VError('problem1'),
    new VError('problem2')
]), 'something bad happened with component1');

var error0 = new VError.WError(new VError.MultiError([ component0, component1 ]),
    'unable to do thing because of problems');

console.error(error0.message);
VError.errorForEach(error0.cause(), function (suberr0) {
        console.error(' -', suberr0.message);
        VError.errorForEach(suberr0.cause(), function (suberr1) {
                console.error('   -', suberr1.message);
        });
});

Prints:

unable to do thing because of problems
 - something bad happened with component0
   - problem0
   - problem1
   - problem2
 - something bad happened with component1
   - problem0
   - problem1
   - problem2

I'll close this issue out.