Skip to main content
Learn how to effectively debug tests using Naite’s callstack tracking feature.

Callstack Tracking Overview

Automatic Collection

Automatic callstack trackingon Naite.t() calls

Call Path

Function call sequenceFile location info

Debugging Support

Identify problem locationTrace root cause

Viewer Integration

Visualize in VSCodeClick to navigate

What is a Callstack?

A callstack is a data structure that tracks the order of function calls during program execution. Naite automatically collects the callstack at the point of Naite.t() calls, allowing you to pinpoint exactly where logs were recorded.

Why is Callstack Important?

In complex applications, a single operation executes through multiple functions. When problems occur, knowing the path through which functions were called makes debugging much easier.

Basic Structure

The callstack information collected by Naite is as follows:
Collected callstack:
Meaning:
  1. createUser (line 15): Location where Naite.t() was actually called
  2. test (line 42): Test code called createUser
  3. runWithMockContext: Sonamu’s Context wrapper (ends here)

How Callstack Collection Works

extractCallStack() Behavior

Naite uses JavaScript’s Error object to collect callstacks.
1

Create Error Object

Get current callstack as string with new Error().stack.
2

Remove Unnecessary Frames

Exclude Error, extractCallStack, Naite.t frames (slice(3)).
3

Parse

Parse each line into StackFrame objects.
4

End at Context Boundary

Cut at runWithContext when encountered. Beyond that is Vitest internal code which is not meaningful.

parseStackFrame() Logic

Parses two callstack formats:
Why End at runWithContext: Naite keeps only meaningful callstacks. runWithContext is Sonamu’s Context boundary, and above it is Vitest’s internal code which doesn’t help with debugging.

Practical Debugging Scenarios

1. Tracing Call Paths

Track only specific paths in complex function call chains.
Check in VSCode: When you click a log in Naite Viewer, the callstack is displayed, and clicking each frame navigates directly to that code location.

2. Finding Error Locations

Find the exact location when an error occurs.
Regular console.log or console.error only shows the error message. But with Naite’s callstack:
  1. Exact File and Line: Exact code location where error occurred
  2. Call Path: Which functions were called leading to the error
  3. VSCode Integration: Navigate to code location with one click
  4. Context: Saved along with data at the time of error
For example, if error occurred in validateUser:
This tells you the error occurred at line 78 in validateUser, which was called from line 45 in createUser, which was started from line 12 in the test.

3. Analyzing Complex Call Chains

Analyze complex chains called in A β†’ B β†’ C β†’ D order.
Visualization:

4. Using fromFunction()

Filter only logs called from a specific function.
Checks only the first frame of the callstack (stack[0]).

VSCode Viewer Integration

Naite Viewer visually displays callstack information and allows you to navigate to code locations with a single click.

Callstack Visualization

When you click each log in Naite Viewer, it displays like this:

Viewer Screen Example

Interaction:
  • Click each frame to have VSCode editor navigate to the exact line in that file
  • Immediately see code context
  • Reduces debugging time

Practical Usage Examples

1

Check Logs in Viewer

After running tests, find suspicious logs in Naite Viewer.
2

Check Callstack

Click the log to view its callstack. Understand which functions it went through.
3

Navigate to Code Location

Click each frame in the callstack to view the actual code.
4

Identify and Fix Problem

Follow the callstack to find and fix the root cause.
Pro Tip: Comparing callstacks of multiple logs in Viewer helps quickly identify differences between normal and abnormal paths.

Advanced Patterns

1. Finding Performance Bottlenecks

Combine callstack and timing information to find performance bottlenecks.

2. Debugging Syncer

Track Syncer’s complex template generation process.

3. Detecting Infinite Loops

Monitor the depth of recursive functions.

4. Conditional Logging

Enable detailed logging only under certain conditions.

Callstack Limitations

Ends at runWithContext

Naite stops callstack collection when it encounters runWithContext or runWithMockContext.
Reasons:
  • runWithContext is Sonamu’s Context boundary
  • Above it is Vitest internal code (meaningless)
  • Keep only meaningful callstack for better readability

node:internal Paths

Node.js internal paths have lineNumber set to 0:
Example:
These frames are Node.js internal operations and don’t help much with debugging.

Anonymous Functions

Arrow functions and anonymous functions have functionName as null:
For easier debugging, give explicit names to important functions:

Best Practices

1

Log at Meaningful Locations

2

Log on Error Situations

3

Use Explicit Function Names

4

Utilize VSCode Viewer

Keep Naite Viewer open during local development and check callstacks by clicking logs. Navigating directly to code locations significantly speeds up debugging.

Cautions

Cautions when using callstack tracking:
  1. Performance: Callstack collection has cost, so avoid excessive logging.
  2. Depth: Deep recursion means longer callstacks. Watch out for infinite recursion.
  3. Anonymous Functions: Anonymous functions have functionName as null. Give important functions explicit names.
  4. Minified Code: Function names may be obfuscated in production builds. But Naite is test-only so this isn’t an issue.
  5. Test Only: Not used in production code (only works when NODE_ENV === "test").

Next Steps

Naite Viewer

Visually check callstacks with VSCode Extension.

Querying Logs

Filter logs from specific functions with fromFunction().

Recording Logs

Learn effective logging strategies.

What is Naite?

Return to Naite overview.