Skip to main content
Pro Plan15 minutesAdvanced

Stack Trace Analysis

Understand and debug JavaScript errors using stack traces with source map support. Learn about stack trace in this error tracking guide.

stack-tracedebuggingsource-mapserrorsanalysis
Last updated:

Master stack trace analysis to quickly identify and fix JavaScript errors in your application.

Zenovay Errors dashboard listing errors you can open to view the stack trace.
Open any error in the Errors tab to see its grouped occurrences and stack trace.

Understanding Stack Traces

Anatomy of a Stack Trace

TypeError: Cannot read property 'email' of undefined
    at getUserEmail (user-service.js:45:12)    ← Error location
    at validateForm (form-handler.js:123:8)    ← Called from here
    at HTMLFormElement.<anonymous> (form.js:67:5) ← Event handler
    at HTMLFormElement.dispatch (jquery.min.js:3:10456)
    at HTMLFormElement.v.handle (jquery.min.js:3:8765)

Stack Frame Components

Each line contains:

ComponentExampleDescription
FunctiongetUserEmailFunction name
Fileuser-service.jsSource file
Line45Line number
Column12Column position

Reading Direction

Read stack traces top to bottom:

  1. Top frame: Where error occurred
  2. Middle frames: Call chain
  3. Bottom frames: Entry point

Viewing Stack Traces in Zenovay

Error tracking is a Pro feature. Once it's enabled for a website, captured errors are grouped by fingerprint and shown on the Errors tab of that website's dashboard (/domains/{your-site}?tab=errors).

To enable it, open the website's settings, go to the Advanced section, and turn on Error Tracking under feature flags.

The Error Detail View

Open an error group from the Errors tab to see its recent occurrences. For each occurrence you can review:

  • The error type and message
  • The page URL where it happened
  • Browser, OS, and device breakdowns
  • The breadcrumbs ("user actions before" the error) leading up to it
  • The stack trace, shown as an expandable list of frames

The stack trace is collapsed by default. Expand it to see each frame as:

at getUserById (user-service.js:45:12)
at handleGetUser (api-handler.js:78:5)
at <anonymous> (router.js:23:3)

Long traces are truncated to the first frames, with a "more frames" indicator for the rest. The function name, file, line, and column are shown for each frame so you can jump straight to the relevant code in your editor.

Source Maps

Source maps let Zenovay turn minified production stack traces back into your original source file, line, and column.

Without Source Maps

Minified code produces cryptic traces:

TypeError: a is not a function
    at e (main.abc123.js:1:34567)
    at t.handleClick (main.abc123.js:1:45678)
    at Object.onClick (main.abc123.js:1:56789)

With Source Maps

Same error, readable:

TypeError: processPayment is not a function
    at handleCheckout (checkout.tsx:89:12)
    at CheckoutButton.handleClick (CheckoutButton.tsx:45:8)
    at onClick (form-events.ts:23:5)

Generating Source Maps

The first step is to generate source maps during your build. Use hidden source maps in production so the .map files are created but never referenced (or served) from your public bundle.

Webpack - generate hidden source maps:

// webpack.config.js
module.exports = {
  devtool: 'hidden-source-map',
  // Source maps generated but not referenced in output
};

Vite - generate hidden source maps:

// vite.config.js
export default {
  build: {
    sourcemap: 'hidden'
  }
};

Rollup - generate hidden source maps:

// rollup.config.js
export default {
  output: {
    sourcemap: 'hidden'
  }
};

Tag each build with a release version (see Release Correlation below) so source maps and errors line up against the same deploy.

Analyzing Common Patterns

Undefined Property Access

TypeError: Cannot read property 'name' of undefined
    at renderUser (user-card.js:23:15)

Analysis:

  • Object expected at line 23 is undefined
  • Check data flow to renderUser
  • Likely missing null check

Fix pattern:

// Before
const name = user.name;

// After
const name = user?.name ?? 'Unknown';

Function Not Defined

ReferenceError: processPayment is not defined
    at handleSubmit (checkout.js:45:5)

Analysis:

  • Function called but not in scope
  • Check imports/exports
  • Verify module loading order

Type Errors

TypeError: users.map is not a function
    at renderUserList (list.js:12:20)

Analysis:

  • users is not an array
  • Check API response format
  • Verify data type assumptions

Advanced Analysis

Async Stack Traces

Modern JavaScript includes async context:

Error: API request failed
    at fetchUser (api.js:34:11)
    at async loadUserData (user-loader.js:56:18)
    at async initApp (app.js:12:5)

Cross-Origin Frames

Third-party scripts show limited info:

Error: Script error.
    at <anonymous> (https://third-party.com/widget.js:1:1)

Solution: Add CORS headers to third-party scripts:

<script src="https://third-party.com/widget.js" crossorigin="anonymous"></script>

Minified Third-Party Code

For libraries without source maps:

  • Identify library from URL pattern
  • Check library version
  • Search for known issues
  • Consider alternatives

Debugging Workflow

Step 1: Identify Error Location

  1. Look at top stack frame
  2. Note file, line, column
  3. Understand what code is doing

Step 2: Trace the Call Path

  1. Follow frames down the stack
  2. Identify data flow
  3. Find where bad data originates

Step 3: Check Context

  1. View the error frequency over time on the Errors tab
  2. Check affected browsers/devices in the breakdown
  3. Read the breadcrumbs leading up to the error

Step 4: Reproduce

  1. Use session replay (if available on your plan)
  2. Check user actions before the error
  3. Test with same browser/conditions

Step 5: Fix and Verify

  1. Implement fix
  2. Deploy new version
  3. Mark the error group as resolved from the error detail view
  4. Monitor for regressions

Managing Error Status

From the error detail view you can change a group's status to keep your list focused:

  • Unresolved — needs attention (the default)
  • Investigating — someone is working on it
  • Resolved — fixed and verified
  • Ignored — known and intentionally not actioned

Status changes require editor access on the workspace and are recorded in the workspace audit log.

Release Correlation

When you tag your tracking with a release, every captured error records the release it came from, so you can tell which deploy introduced a problem.

Tag Releases

Set a release value in your build so the tracker reports it with each event. The base snippet looks like this:

<script
  defer
  data-tracking-code="YOUR_TRACKING_CODE"
  src="https://api.zenovay.com/z.js"
></script>

Pair this with the matching source maps from your build (tagged with the same release) so production traces symbolicate against the correct version.

Best Practices

Source Map Management

  • Use hidden source maps in production
  • Keep source maps organized by release
  • Tag each build with the release version that matches your deploy

Stack Trace Quality

  • Use meaningful function names
  • Avoid anonymous functions
  • Keep call stacks reasonable depth
  • Add error context where needed

Debugging Efficiency

  • Start with most impacted errors
  • Use status (investigating, resolved, ignored) to focus the list
  • Document findings
  • Share with your team

Troubleshooting

Missing Source Maps

Check:

  • Source maps were generated for this release
  • The release version matches what the tracker reports
  • File names line up with your deployed bundles

Incomplete Stack Traces

Causes:

  • Async code not properly traced
  • Errors from eval() or dynamic code
  • Browser limitations

"Script error" Messages

Solutions:

  • Add CORS headers
  • Use the crossorigin attribute
  • Self-host third-party scripts

Next Steps

Was this article helpful?