Skip to content

Commit

Permalink
Do not throw on custom stack traces (#1491)
Browse files Browse the repository at this point in the history
  • Loading branch information
tabarra authored Nov 2, 2020
1 parent 2b8ed1f commit 49c16ee
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 1 deletion.
2 changes: 1 addition & 1 deletion source/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1218,7 +1218,7 @@ export class RequestError extends Error {
this.timings = this.request?.timings;

// Recover the original stacktrace
if (!is.undefined(error.stack)) {
if (is.string(error.stack) && is.string(this.stack)) {
const indexOfMessage = this.stack.indexOf(this.message) + this.message.length;
const thisStackTrace = this.stack.slice(indexOfMessage).split('\n').reverse();
const errorStackTrace = error.stack.slice(error.stack.indexOf(error.message!) + error.message!.length).split('\n').reverse();
Expand Down
69 changes: 69 additions & 0 deletions test/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import net = require('net');
import http = require('http');
import stream = require('stream');
import test from 'ava';
import getStream = require('get-stream');
import is from '@sindresorhus/is';
import got, {RequestError, HTTPError, TimeoutError} from '../source';
import withServer from './helpers/with-server';

Expand Down Expand Up @@ -261,3 +263,70 @@ test.skip('the old stacktrace is recovered', async t => {
// the second `at get` points to the real cause.
t.not(error.stack!.indexOf('at get'), error.stack!.lastIndexOf('at get'));
});

test.serial('custom stack trace', withServer, async (t, _server, got) => {
const ErrorCaptureStackTrace = Error.captureStackTrace;

const enable = () => {
Error.captureStackTrace = (target: {stack: any}) => {
target.stack = [
'line 1',
'line 2'
];
};
};

const disable = () => {
Error.captureStackTrace = ErrorCaptureStackTrace;
};

// Node.js default behavior
{
const stream = got.stream('');
stream.destroy(new Error('oh no'));

const caught = await t.throwsAsync(getStream(stream));
t.is(is(caught.stack), 'string');
}

// Passing a custom error
{
enable();
const error = new Error('oh no');
disable();

const stream = got.stream('');
stream.destroy(error);

const caught = await t.throwsAsync(getStream(stream));
t.is(is(caught.stack), 'string');
}

// Custom global behavior
{
enable();
const error = new Error('oh no');

const stream = got.stream('');
stream.destroy(error);

const caught = await t.throwsAsync(getStream(stream));
t.is(is(caught.stack), 'Array');

disable();
}

// Passing a default error that needs some processing
{
const error = new Error('oh no');
enable();

const stream = got.stream('');
stream.destroy(error);

const caught = await t.throwsAsync(getStream(stream));
t.is(is(caught.stack), 'Array');

disable();
}
});

0 comments on commit 49c16ee

Please sign in to comment.