lib: refactor Error.captureStackTrace() usage · nodejs/node@bfbce28 (original) (raw)

`@@ -18,7 +18,7 @@ const codes = {};

`

18

18

`const { kMaxLength } = internalBinding('buffer');

`

19

19

`const { defineProperty } = Object;

`

20

20

``

21

``

`-

let useOriginalName = false;

`

``

21

`+

let excludedStackFn;

`

22

22

``

23

23

`// Lazily loaded

`

24

24

`let util;

`

`@@ -49,7 +49,15 @@ function lazyBuffer() {

`

49

49

`// and may have .path and .dest.

`

50

50

`class SystemError extends Error {

`

51

51

`constructor(key, context) {

`

52

``

`-

super();

`

``

52

`+

if (excludedStackFn === undefined) {

`

``

53

`+

super();

`

``

54

`+

} else {

`

``

55

`+

const limit = Error.stackTraceLimit;

`

``

56

`+

Error.stackTraceLimit = 0;

`

``

57

`+

super();

`

``

58

`+

// Reset the limit and setting the name property.

`

``

59

`+

Error.stackTraceLimit = limit;

`

``

60

`+

}

`

53

61

`const prefix = getMessage(key, [], this);

`

54

62

`` let message = ${prefix}: ${context.syscall} returned +

``

55

63

`` ${context.code} (${context.message});

``

`@@ -148,7 +156,15 @@ function makeSystemErrorWithCode(key) {

`

148

156

`function makeNodeErrorWithCode(Base, key) {

`

149

157

`return class NodeError extends Base {

`

150

158

`constructor(...args) {

`

151

``

`-

super();

`

``

159

`+

if (excludedStackFn === undefined) {

`

``

160

`+

super();

`

``

161

`+

} else {

`

``

162

`+

const limit = Error.stackTraceLimit;

`

``

163

`+

Error.stackTraceLimit = 0;

`

``

164

`+

super();

`

``

165

`+

// Reset the limit and setting the name property.

`

``

166

`+

Error.stackTraceLimit = limit;

`

``

167

`+

}

`

152

168

`const message = getMessage(key, args, this);

`

153

169

`Object.defineProperty(this, 'message', {

`

154

170

`value: message,

`

`@@ -178,9 +194,30 @@ function makeNodeErrorWithCode(Base, key) {

`

178

194

`};

`

179

195

`}

`

180

196

``

``

197

`+

// This function removes unnecessary frames from Node.js core errors.

`

``

198

`+

function hideStackFrames(fn) {

`

``

199

`+

return function hidden(...args) {

`

``

200

`` +

// Make sure the most outer hideStackFrames() function is used.

``

``

201

`+

let setStackFn = false;

`

``

202

`+

if (excludedStackFn === undefined) {

`

``

203

`+

excludedStackFn = hidden;

`

``

204

`+

setStackFn = true;

`

``

205

`+

}

`

``

206

`+

try {

`

``

207

`+

return fn(...args);

`

``

208

`+

} finally {

`

``

209

`+

if (setStackFn === true) {

`

``

210

`+

excludedStackFn = undefined;

`

``

211

`+

}

`

``

212

`+

}

`

``

213

`+

};

`

``

214

`+

}

`

``

215

+

181

216

`function addCodeToName(err, name, code) {

`

182

``

`-

if (useOriginalName) {

`

183

``

`-

return;

`

``

217

`+

// Set the stack

`

``

218

`+

if (excludedStackFn !== undefined) {

`

``

219

`+

// eslint-disable-next-line no-restricted-syntax

`

``

220

`+

Error.captureStackTrace(err, excludedStackFn);

`

184

221

`}

`

185

222

`// Add the error code to the name to include it in the stack trace.

`

186

223

`` err.name = ${name} [${code}];

``

`@@ -308,6 +345,7 @@ function uvException(ctx) {

`

308

345

`err[prop] = ctx[prop];

`

309

346

`}

`

310

347

``

``

348

`` +

// TODO(BridgeAR): Show the code property as part of the stack.

``

311

349

`err.code = code;

`

312

350

`if (path) {

`

313

351

`err.path = path;

`

`@@ -316,7 +354,7 @@ function uvException(ctx) {

`

316

354

`err.dest = dest;

`

317

355

`}

`

318

356

``

319

``

`-

Error.captureStackTrace(err, uvException);

`

``

357

`+

Error.captureStackTrace(err, excludedStackFn || uvException);

`

320

358

`return err;

`

321

359

`}

`

322

360

``

`@@ -358,7 +396,7 @@ function uvExceptionWithHostPort(err, syscall, address, port) {

`

358

396

`ex.port = port;

`

359

397

`}

`

360

398

``

361

``

`-

Error.captureStackTrace(ex, uvExceptionWithHostPort);

`

``

399

`+

Error.captureStackTrace(ex, excludedStackFn || uvExceptionWithHostPort);

`

362

400

`return ex;

`

363

401

`}

`

364

402

``

`@@ -386,7 +424,7 @@ function errnoException(err, syscall, original) {

`

386

424

`ex.code = ex.errno = code;

`

387

425

`ex.syscall = syscall;

`

388

426

``

389

``

`-

Error.captureStackTrace(ex, errnoException);

`

``

427

`+

Error.captureStackTrace(ex, excludedStackFn || errnoException);

`

390

428

`return ex;

`

391

429

`}

`

392

430

``

`@@ -434,7 +472,7 @@ function exceptionWithHostPort(err, syscall, address, port, additional) {

`

434

472

`ex.port = port;

`

435

473

`}

`

436

474

``

437

``

`-

Error.captureStackTrace(ex, exceptionWithHostPort);

`

``

475

`+

Error.captureStackTrace(ex, excludedStackFn || exceptionWithHostPort);

`

438

476

`return ex;

`

439

477

`}

`

440

478

``

`@@ -473,7 +511,8 @@ function dnsException(code, syscall, hostname) {

`

473

511

`if (hostname) {

`

474

512

`ex.hostname = hostname;

`

475

513

`}

`

476

``

`-

Error.captureStackTrace(ex, dnsException);

`

``

514

+

``

515

`+

Error.captureStackTrace(ex, excludedStackFn || dnsException);

`

477

516

`return ex;

`

478

517

`}

`

479

518

``

`@@ -523,21 +562,19 @@ function oneOf(expected, thing) {

`

523

562

`}

`

524

563

``

525

564

`module.exports = {

`

``

565

`+

addCodeToName, // Exported for NghttpError

`

``

566

`+

codes,

`

526

567

` dnsException,

`

527

568

` errnoException,

`

528

569

` exceptionWithHostPort,

`

``

570

`+

getMessage,

`

``

571

`+

hideStackFrames,

`

``

572

`+

isStackOverflowError,

`

529

573

` uvException,

`

530

574

` uvExceptionWithHostPort,

`

531

``

`-

isStackOverflowError,

`

532

``

`-

getMessage,

`

533

575

` SystemError,

`

534

``

`-

codes,

`

535

576

`// This is exported only to facilitate testing.

`

536

``

`-

E,

`

537

``

`-

// This allows us to tell the type of the errors without using

`

538

``

`-

// instanceof, which is necessary in WPT harness.

`

539

``

`-

get useOriginalName() { return useOriginalName; },

`

540

``

`-

set useOriginalName(value) { useOriginalName = value; }

`

``

577

`+

E

`

541

578

`};

`

542

579

``

543

580

`// To declare an error message, use the E(sym, val, def) function above. The sym

`

`@@ -556,7 +593,6 @@ module.exports = {

`

556

593

`// Note: Please try to keep these in alphabetical order

`

557

594

`//

`

558

595

`// Note: Node.js specific errors must begin with the prefix ERR_

`

559

``

-

560

596

`E('ERR_AMBIGUOUS_ARGUMENT', 'The "%s" argument is ambiguous. %s', TypeError);

`

561

597

`E('ERR_ARG_NOT_ITERABLE', '%s must be iterable', TypeError);

`

562

598

`E('ERR_ASSERTION', '%s', Error);

`

`@@ -630,7 +666,10 @@ E('ERR_ENCODING_INVALID_ENCODED_DATA', function(encoding, ret) {

`

630

666

`}, TypeError);

`

631

667

`E('ERR_ENCODING_NOT_SUPPORTED', 'The "%s" encoding is not supported',

`

632

668

`RangeError);

`

633

``

`-

E('ERR_FALSY_VALUE_REJECTION', 'Promise was rejected with falsy value', Error);

`

``

669

`+

E('ERR_FALSY_VALUE_REJECTION', function(reason) {

`

``

670

`+

this.reason = reason;

`

``

671

`+

return 'Promise was rejected with falsy value';

`

``

672

`+

}, Error);

`

634

673

`E('ERR_FS_FILE_TOO_LARGE', 'File size (%s) is greater than possible Buffer: ' +

`

635

674

`` ${kMaxLength} bytes,

``

636

675

`RangeError);

`