0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-04-08 02:52:39 -05:00

@tryghost/errors Add stack related functions

refs: https://github.com/TryGhost/Toolbox/issues/147

Correctly prepares the stack when wrapping another error, and adds a new method on errors to create an error which can be shown to the user (i.e. remove the stack trace in production)
This commit is contained in:
Sam Lord 2021-12-01 17:28:42 +00:00
parent e66cba66f1
commit d8ee09d0fa
3 changed files with 42 additions and 4 deletions

View file

@ -1,6 +1,7 @@
const uuid = require('uuid');
const merge = require('lodash/merge');
const isString = require('lodash/isString');
const cloneDeep = require('lodash/cloneDeep');
const utils = require('./utils');
class GhostError extends Error {
@ -59,7 +60,10 @@ class GhostError extends Error {
}
if (property === 'stack') {
this[property] += '\n\n' + options.err[property];
if (this.hideStack) {
return;
}
this[property] = utils.wrapStack(this, options.err);
return;
}
@ -67,6 +71,34 @@ class GhostError extends Error {
});
}
}
prepareErrorForUser() {
const error = cloneDeep(this);
let stackbits = error.stack.split(/\n/);
// We build this up backwards, so we always insert at position 1
if (process.env.NODE_ENV === 'production') {
stackbits.splice(1, stackbits.length - 1);
} else {
// Clearly mark the strack trace
stackbits.splice(1, 0, `Stack Trace:`);
}
// Add in our custom cotext and help methods
if (this.help) {
stackbits.splice(1, 0, `${this.help}`);
}
if (this.context) {
stackbits.splice(1, 0, `${this.context}`);
}
error.stack = stackbits.join('\n');
return error;
}
}
const ghostErrors = {
@ -95,7 +127,8 @@ const ghostErrors = {
super(merge({
statusCode: 404,
errorType: 'NotFoundError',
message: 'Resource could not be found.'
message: 'Resource could not be found.',
hideStack: true
}, options));
}
},

View file

@ -127,6 +127,12 @@ _private.JSONAPIDeserialize = function JSONAPIDeserialize(errorFormat) {
return internalError;
};
exports.wrapStack = function wrapStack(err, internalErr) {
const extraLine = err.stack.split(/\n/g)[1];
const [firstLine, ...rest] = internalErr.stack.split(/\n/g);
return [firstLine, extraLine, ...rest].join('\n');
};
/**
* @description Serialize GhostError instance to error JSON format
*

View file

@ -64,9 +64,8 @@ describe('Errors', function () {
it('error is string', function () {
var ghostError = new errors.InternalServerError({
err: 'string'
err: new Error('string')
});
ghostError.stack.should.match(/Error: string/);
});
});