or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-stack-utils

Captures and cleans stack traces for JavaScript applications

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/stack-utils@2.0.x

To install, run

npx @tessl/cli install tessl/npm-stack-utils@2.0.0

0

# Stack Utils

1

2

Stack Utils is a JavaScript library for capturing, cleaning, and manipulating stack traces in Node.js applications. It provides powerful utilities to remove internal Node.js lines from stack traces, shorten file paths relative to a working directory, and parse individual stack trace lines into structured objects. Originally extracted from the node-tap testing framework, it's particularly useful for testing frameworks, error handling systems, and debugging tools that need to present clean, readable stack traces.

3

4

## Package Information

5

6

- **Package Name**: stack-utils

7

- **Package Type**: npm

8

- **Language**: JavaScript

9

- **Installation**: `npm install stack-utils`

10

11

## Core Imports

12

13

```javascript

14

const StackUtils = require('stack-utils');

15

```

16

17

## Basic Usage

18

19

```javascript

20

const StackUtils = require('stack-utils');

21

22

// Create a new instance with default settings

23

const stack = new StackUtils({

24

cwd: process.cwd(),

25

internals: StackUtils.nodeInternals()

26

});

27

28

// Clean a stack trace from an error

29

console.log(stack.clean(new Error().stack));

30

31

// Capture current stack trace as string

32

const currentStack = stack.captureString();

33

console.log(currentStack);

34

35

// Get information about current location

36

const location = stack.at();

37

console.log(location); // { line: 15, column: 23, file: 'app.js' }

38

```

39

40

## Capabilities

41

42

### Constructor

43

44

Creates a new StackUtils instance with customizable filtering and formatting options.

45

46

```javascript { .api }

47

/**

48

* Creates a new StackUtils instance

49

* @param options - Configuration options

50

*/

51

new StackUtils(options);

52

53

interface StackUtilsOptions {

54

/** Array of npm package names to ignore in stack traces */

55

ignoredPackages?: string[];

56

/** Array of RegExp patterns for internal lines to filter */

57

internals?: RegExp[];

58

/** Current working directory for relative path resolution */

59

cwd?: string;

60

/** Optional function to wrap CallSite objects */

61

wrapCallSite?: (callSite: CallSite) => CallSite;

62

}

63

```

64

65

**Usage Example:**

66

67

```javascript

68

const stack = new StackUtils({

69

cwd: process.cwd(),

70

ignoredPackages: ['lodash', 'bluebird'],

71

internals: StackUtils.nodeInternals().concat([

72

/\/my-internal-module\//

73

]),

74

wrapCallSite: (callSite) => {

75

// Custom CallSite manipulation for source maps

76

return callSite;

77

}

78

});

79

```

80

81

### Static Methods

82

83

#### Node Internals

84

85

Returns default regular expressions for filtering Node.js internal stack trace lines.

86

87

```javascript { .api }

88

/**

89

* Get default RegExp patterns for Node.js internals

90

* @returns Array of RegExp objects for filtering Node.js internal lines

91

*/

92

static nodeInternals(): RegExp[];

93

```

94

95

### Stack Trace Cleaning

96

97

#### Clean Stack Traces

98

99

Removes internal lines and formats stack traces for better readability.

100

101

```javascript { .api }

102

/**

103

* Clean and format a stack trace by removing internal lines

104

* @param stack - Stack trace string or array of lines

105

* @param indent - Number of spaces to indent each line

106

* @returns Cleaned stack trace string

107

*/

108

clean(stack: string | string[], indent?: number): string;

109

```

110

111

**Usage Examples:**

112

113

```javascript

114

// Clean an error stack trace

115

try {

116

throw new Error('Something went wrong');

117

} catch (err) {

118

const cleanStack = stack.clean(err.stack);

119

console.log(cleanStack);

120

}

121

122

// Clean with custom indentation

123

const indentedStack = stack.clean(err.stack, 4);

124

125

// Clean an array of stack lines

126

const stackLines = err.stack.split('\n');

127

const cleaned = stack.clean(stackLines);

128

```

129

130

### Stack Trace Capture

131

132

#### Capture as String

133

134

Captures the current stack trace and returns it as a cleaned string.

135

136

```javascript { .api }

137

/**

138

* Capture current stack trace as cleaned string

139

* @param limit - Maximum number of stack frames or start function

140

* @param fn - Function to start capture from

141

* @returns Cleaned stack trace string

142

*/

143

captureString(limit?: number | function, fn?: function): string;

144

```

145

146

**Usage Examples:**

147

148

```javascript

149

// Capture current stack with default settings

150

const stack1 = stackUtils.captureString();

151

152

// Limit to 5 frames

153

const stack2 = stackUtils.captureString(5);

154

155

// Start capture from specific function

156

function myFunction() {

157

return stackUtils.captureString(myFunction);

158

}

159

160

// Using limit and start function

161

const stack3 = stackUtils.captureString(10, myFunction);

162

```

163

164

#### Capture as CallSites

165

166

Captures the current stack trace as an array of CallSite objects for programmatic analysis.

167

168

```javascript { .api }

169

/**

170

* Capture current stack trace as CallSite objects

171

* @param limit - Maximum number of stack frames or start function

172

* @param fn - Function to start capture from

173

* @returns Array of CallSite objects

174

*/

175

capture(limit?: number | function, fn?: function): CallSite[];

176

```

177

178

### Location Information

179

180

#### Get Current Location

181

182

Captures information about the current execution location as a serializable object.

183

184

```javascript { .api }

185

/**

186

* Get current execution location information

187

* @param fn - Function to start capture from

188

* @returns Object with location information

189

*/

190

at(fn?: function): LocationInfo;

191

192

interface LocationInfo {

193

/** Line number */

194

line?: number;

195

/** Column number */

196

column?: number;

197

/** File path (relative to cwd) */

198

file?: string;

199

/** Whether this is a constructor call */

200

constructor?: boolean;

201

/** Eval origin information if applicable */

202

evalOrigin?: string;

203

/** Whether this is native code */

204

native?: boolean;

205

/** Type name */

206

type?: string;

207

/** Function name */

208

function?: string;

209

/** Method name */

210

method?: string;

211

}

212

```

213

214

**Usage Examples:**

215

216

```javascript

217

function exampleFunction() {

218

const location = stack.at();

219

console.log(`Called from ${location.file}:${location.line}:${location.column}`);

220

console.log(`Function: ${location.function}`);

221

}

222

223

// Get location starting from specific function

224

function wrapper() {

225

const location = stack.at(wrapper);

226

return location;

227

}

228

```

229

230

### Stack Line Parsing

231

232

#### Parse Individual Lines

233

234

Parses a single stack trace line into a structured object with detailed information.

235

236

```javascript { .api }

237

/**

238

* Parse a single stack trace line into structured object

239

* @param line - Single line from a stack trace

240

* @returns Parsed line information or null if no match

241

*/

242

parseLine(line: string): ParsedLine | null;

243

244

interface ParsedLine {

245

/** Line number */

246

line?: number;

247

/** Column number */

248

column?: number;

249

/** File path */

250

file?: string;

251

/** Whether this is a constructor call */

252

constructor?: boolean;

253

/** Eval origin information */

254

evalOrigin?: string;

255

/** Eval line number */

256

evalLine?: number;

257

/** Eval column number */

258

evalColumn?: number;

259

/** Eval file path */

260

evalFile?: string;

261

/** Whether this is native code */

262

native?: boolean;

263

/** Function name */

264

function?: string;

265

/** Method name */

266

method?: string;

267

}

268

```

269

270

**Usage Examples:**

271

272

```javascript

273

// Parse individual stack trace lines

274

const stackTrace = new Error().stack;

275

const lines = stackTrace.split('\n');

276

277

lines.forEach(line => {

278

const parsed = stack.parseLine(line);

279

if (parsed) {

280

console.log(`${parsed.function} in ${parsed.file}:${parsed.line}`);

281

}

282

});

283

284

// Handle different line formats

285

const testLines = [

286

' at myFunction (app.js:10:5)',

287

' at new Constructor (lib.js:25:12)',

288

' at eval (eval at <anonymous> (app.js:5:1), <anonymous>:1:1)',

289

' at native'

290

];

291

292

testLines.forEach(line => {

293

const result = stack.parseLine(line);

294

console.log(result);

295

});

296

```

297

298

## Types

299

300

### CallSite Interface

301

302

The native V8 CallSite interface provides detailed information about stack frames.

303

304

```javascript { .api }

305

interface CallSite {

306

getThis(): any;

307

getTypeName(): string | null;

308

getFunction(): Function;

309

getFunctionName(): string | null;

310

getMethodName(): string | null;

311

getFileName(): string | null;

312

getLineNumber(): number | null;

313

getColumnNumber(): number | null;

314

getEvalOrigin(): string | null;

315

isToplevel(): boolean;

316

isEval(): boolean;

317

isNative(): boolean;

318

isConstructor(): boolean;

319

}

320

```

321

322

## Error Handling

323

324

Stack Utils gracefully handles various edge cases:

325

326

- **Invalid stack traces**: Returns empty results for malformed input

327

- **Missing files**: Handles stack traces with missing or invalid file paths

328

- **Native code**: Properly identifies and handles native code frames

329

- **Eval contexts**: Parses and preserves eval origin information

330

- **Process availability**: Works even when `process` object is not available

331

332

## Common Use Cases

333

334

### Testing Frameworks

335

336

```javascript

337

const StackUtils = require('stack-utils');

338

339

class TestFramework {

340

constructor() {

341

this.stack = new StackUtils({

342

ignoredPackages: ['tap', 'mocha', 'jest'],

343

cwd: process.cwd()

344

});

345

}

346

347

reportError(error) {

348

console.error('Test failed:');

349

console.error(this.stack.clean(error.stack, 2));

350

}

351

352

getCurrentTestLocation() {

353

return this.stack.at(this.reportError);

354

}

355

}

356

```

357

358

### Error Logging

359

360

```javascript

361

const StackUtils = require('stack-utils');

362

363

const logger = {

364

stack: new StackUtils({

365

ignoredPackages: ['winston', 'pino'],

366

cwd: process.cwd()

367

}),

368

369

error(message, error) {

370

console.log({

371

message,

372

stack: this.stack.clean(error.stack),

373

location: this.stack.at(this.error)

374

});

375

}

376

};

377

```

378

379

### Debug Information

380

381

```javascript

382

const StackUtils = require('stack-utils');

383

384

function createDebugger(namespace) {

385

const stack = new StackUtils();

386

387

return function debug(message) {

388

const location = stack.at(debug);

389

console.log(`[${namespace}] ${location.file}:${location.line} - ${message}`);

390

};

391

}

392

393

const debug = createDebugger('myapp');

394

debug('Something happened'); // [myapp] app.js:15 - Something happened

395

```