admin管理员组

文章数量:1406926

I want to copy Javascript Error without reference.

Example:

const error1 = new Error('error1');
const error2 = error1;

error2.message = 'error2';

console.log(error1);
console.log(error2);

Output:

Error: error2
    at evalmachine.<anonymous>:1:16
    at Script.runInContext (vm.js:133:20)
    at Object.runInContext (vm.js:311:6)
    at evaluate (/run_dir/repl.js:133:14)
    at ReadStream.<anonymous> (/run_dir/repl.js:116:5)
    at ReadStream.emit (events.js:198:13)
    at addChunk (_stream_readable.js:288:12)
    at readableAddChunk (_stream_readable.js:269:11)
    at ReadStream.Readable.push (_stream_readable.js:224:10)
    at lazyFs.read (internal/fs/streams.js:181:12)

Error: error2
    at evalmachine.<anonymous>:1:16
    at Script.runInContext (vm.js:133:20)
    at Object.runInContext (vm.js:311:6)
    at evaluate (/run_dir/repl.js:133:14)
    at ReadStream.<anonymous> (/run_dir/repl.js:116:5)
    at ReadStream.emit (events.js:198:13)
    at addChunk (_stream_readable.js:288:12)
    at readableAddChunk (_stream_readable.js:269:11)
    at ReadStream.Readable.push (_stream_readable.js:224:10)
    at lazyFs.read (internal/fs/streams.js:181:12)

When i change error2 then error1 will also change. then I tried lodash clone feature. But unfortunately it instead returns an object, not an instance of Error. is there a way so that I can copy an Error without reference and return an instanceof Error without changing stack or other default properties?

I want to copy Javascript Error without reference.

Example:

const error1 = new Error('error1');
const error2 = error1;

error2.message = 'error2';

console.log(error1);
console.log(error2);

Output:

Error: error2
    at evalmachine.<anonymous>:1:16
    at Script.runInContext (vm.js:133:20)
    at Object.runInContext (vm.js:311:6)
    at evaluate (/run_dir/repl.js:133:14)
    at ReadStream.<anonymous> (/run_dir/repl.js:116:5)
    at ReadStream.emit (events.js:198:13)
    at addChunk (_stream_readable.js:288:12)
    at readableAddChunk (_stream_readable.js:269:11)
    at ReadStream.Readable.push (_stream_readable.js:224:10)
    at lazyFs.read (internal/fs/streams.js:181:12)

Error: error2
    at evalmachine.<anonymous>:1:16
    at Script.runInContext (vm.js:133:20)
    at Object.runInContext (vm.js:311:6)
    at evaluate (/run_dir/repl.js:133:14)
    at ReadStream.<anonymous> (/run_dir/repl.js:116:5)
    at ReadStream.emit (events.js:198:13)
    at addChunk (_stream_readable.js:288:12)
    at readableAddChunk (_stream_readable.js:269:11)
    at ReadStream.Readable.push (_stream_readable.js:224:10)
    at lazyFs.read (internal/fs/streams.js:181:12)

When i change error2 then error1 will also change. then I tried lodash clone feature. But unfortunately it instead returns an object, not an instance of Error. is there a way so that I can copy an Error without reference and return an instanceof Error without changing stack or other default properties?

Share Improve this question asked Oct 16, 2019 at 6:46 Laode Muhammad Al FatihLaode Muhammad Al Fatih 4,6401 gold badge22 silver badges38 bronze badges 6
  • 1 What is it that you're trying to acplish with this? – JLRishe Commented Oct 16, 2019 at 6:48
  • I have several functions that send errors in their parameters, I don't want the original Error to be interrupted. So I want to copy an Error for each function. Like formats in winston. – Laode Muhammad Al Fatih Commented Oct 16, 2019 at 7:00
  • Its because when you assign it you are creating a reference, try assigning only the member you are interested in and wrap in String(). – SPlatten Commented Oct 16, 2019 at 7:01
  • 2 But why would any of the handlers mutate the error object? – mbojko Commented Oct 16, 2019 at 7:07
  • 1 winston library makes info parameter as instanceof Error if you input an Error to their logger. I need to change some properties in the info parameter, because winston store their message in info[Symbol('message')] – Laode Muhammad Al Fatih Commented Oct 16, 2019 at 7:17
 |  Show 1 more ment

2 Answers 2

Reset to default 4

You can try entering some important properties manually:

const error1 = new Error('error1');
const error2 = new error1.constructor(error1.message);

if (error1.stack) {
  error2.stack = error1.stack;
}

if (error1.code) {
  error2.code = error1.code;
}

if (error1.errno) {
  error2.errno = error1.errno;
}

if (error1.syscall) {
  error2.syscall = error1.syscall;
}

error2.message = 'error2';

console.log(error1);
console.log(error2);

If you insist on having separate copies of the error, I think your best bet is to create a new error and copy over the properties you want to preserve:

function copyError(err, newMessage) {
    var newErr = new Error(newMessage);

    newErr.stack = err.stack;
    // copy other properties
}

var newErr = copyError(e, "New message");

However, I don't think is such a great approach.

Another option would be to do something like what .NET does - create a new error and place the original error on a property of that error:

var newErr = new Error("New message");
newErr.innerError = originalError;

The drawback here is that anything inspecting these errors would need to check for the presence of an .innerError property and use it accordingly.

本文标签: objectHow do I copy Javascript Error without referenceStack Overflow