How to delete the final element in a stack trace string using Javascript

Currently, I am working on a Javascript logger that includes the stack trace in error messages. The implementation looks like this:

function logMessage(logMessage) 
{
  let stackTrace = new Error().stack;
  logMessage.stackTrace = stackTrace;
  ...
}

While this approach provides me with the stack trace, it also adds the method of logMessage at the end of the stack...

Is there a way for me to remove the last trace so that I only view the trace leading up to the point where logMessage was called, excluding logMessage itself?

Answer №1

The process is actually quite straightforward given that the stack we receive is a string separated by \n, structured as follows:

ERROR \n
at ... \n
at ... \n

Therefore, all that needs to be done is:

let errorStack = new Error().stack;   //retrieve the stack trace string
let lines = errorStack.split("\n");    //generate an array with individual lines
lines.splice(1,1);                     //delete the second line (first line after "ERROR")
errorStack = lines.join("\n");         //recombine the array into a string

Answer №2

When a stack trace is generated, it results in a multiline string that begins with the error message followed by lines starting with at {function name/position}.

To modify the multiline string and exclude the first instance of at {function name/position}, you can utilize methods such as split, filter, and join.

stackTrace.split('\n').filter(function(line, index) { return index !== 1 }).join('\n');

Check out the code snippet below for an example:

function deepFunctionStack() {
  return new Error().stack;
}

function layer1Function() {
  return deepFunctionStack();
}

function topLayerFunction() {
  return layer1Function();
}

var originalStack = topLayerFunction();
var formattedStack = originalStack.split('\n').filter(function(line, index) { return index !== 1 }).join('\n');
document.write('Original Stack:');
document.write('<pre>' + originalStack + '</pre>');

document.write('Formatted Stack:');
document.write('<pre>' + formattedStack + '</pre>');

Answer №3

Here is a revised version that caters to the distinctions between Firefox, Chrome, and Internet Explorer stack traces. It eliminates the initial "ERROR" line from Chrome and IE, making it notably quicker than other variants mentioned here.

// stack: string - call stack string
// levels: int - number of levels to remove from the top of the call stack
function trimCallStack(stack, levels) {
    if (stack) {
        const newLineChar = "\n"; // Each line delimited by '\n'
        const isFirefoxCallStack = stack.indexOf("@") > -1; // If stacktrace contains '@' it is FireFox
        // Remove an extra line if browser isn't FireFox (i.e., Chrome or IE) as they start the stack trace with the error name
        // Remove N additional lines specified by `levels`
        let iterations = (isFirefoxCallStack ? 0 : 1) + (levels ?? 0);
        let start = 0;
        while(iterations-- && start !== -1) {
            start = stack.indexOf(newLineChar, start + 1);
        }
        
        stack = start !== -1 ? stack.substring(start + 1) : ""; // start === -1 if removing more lines than exist, so return "" in that case
    }

    return stack || "";
}

Examples of stack traces from Firefox and Chrome/IE:

Chrome/IE stacktrace:

Error: fail
    at test (<anonymous>:2:8)
    at test1 (<anonymous>:5:5)
    at test2 (<anonymous>:8:5)
    at test3 (<anonymous>:11:5)
    at <anonymous>:1:5

Firefox stacktrace:

test@debugger eval code:2:8
test1@debugger eval code:5:5
test2@debugger eval code:8:5
test3@debugger eval code:11:5
@debugger eval code:1:5

After implementing the provided function:

Chrome/IE stacktrace:

    at test (<anonymous>:2:8)
    at test1 (<anonymous>:5:5)
    at test2 (<anonymous>:8:5)
    at test3 (<anonymous>:11:5)
    at <anonymous>:1:5

Firefox stacktrace:

test@debugger eval code:2:8
test1@debugger eval code:5:5
test2@debugger eval code:8:5
test3@debugger eval code:11:5
@debugger eval code:1:5

Answer №4

In the past, I utilized this Q&A to edit my stacktrace before sending it to Sentry.

However, I want to highlight that for those using this method with Sentry, it is no longer necessary. Sentry offers a way to adjust the priority of stacktraces in case of an error.

For instance, if we wanted to exclude the function logMessage, we would include:

stack.function:captureError          -app -group

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Developing a feature to organize content by categories and implement a functionality to load more data efficiently using NodeJS routes

I am looking to develop a system that limits the number of displayed posts and includes a "load more" button to retrieve additional posts from where the limit was previously reached. Additionally, I want to implement the functionality to change the orderin ...

What is the default delay when utilizing the $timeout function in AngularJS?

While looking at the concise information on the AngularJS $timeout documentation page, I noticed that the 'delay' argument is listed as optional. However, when utilizing $timeout without specifying a delay, I observed that a delay is still implem ...

The steps to triggering a button click after e.preventDefault()

When attempting to prevent a click() event of a button by using preventDefault() after unbinding the button with unbind(), I encountered an issue where it did not work as expected. <script> $("#update2FAButton").on("click",function(e){ e.pre ...

JavaScript popup cannot be shown at this time

I'm encountering an issue with displaying popups using JavaScript. Currently, only the div with class "popup" is being shown. When a user takes action, both popup and popup2 should be displayed but for some reason, it's not working as expected. ...

Determine the existence of a document/record in MongoDB

I am having trouble using .find({}) with MongoDB as it is not returning the expected response. I'm not sure how to determine if the document exists or not. What I want to achieve is: If a document exists, then do something - like sending a response b ...

Unveiling the secret to accessing properties using v-if within a custom component template relocation

I'm currently working on an application that reveals a hidden div when the text "Create Test" is clicked. Everything works well when the code isn't placed inside the template of a component. This seems strange to me, what could be causing this is ...

Struggling with a character entity in Javascript? Learn how to escape it and avoid any display issues (such as showing

document.title = ("welcome &rarr; farewell"); Trying to display the arrow symbol "→" but it's not showing correctly. Any tips on how to properly escape it? ...

Executing JavaScript code in the Selenium IDE

I'm having trouble figuring out how to execute JavaScript within the Selenium IDE. The objective is to enter text into an input field, with a backend setup that verifies the current time in the input field for testing purposes: Here's the input f ...

Is it mandatory to employ the spread operator in the process of updating an object while using the useState hook?

Recently delving into hooks, I stumbled upon an insightful passage in the official documentation regarding Using Multiple State Variables: It is noteworthy that updating a state variable in hooks replaces it entirely, as opposed to merging it like in th ...

Ways to retrieve text from a specific column using pandas

In my pandas dataframe, there is a column with values like "1_A01_1_1_NA". I need to extract the text between the underscores such as "A01", "1", "1", and "NA". I attempted to use functions like left, right, and mid but encountered issues when the value ch ...

Tips and tricks for storing and retrieving form state using local storage with jQuery in JavaScript

I'm trying to save the form state in localstorage, I am able to save it successfully but I'm encountering an issue where I am unable to save the input typed data Desired outcome: If I type doggy inside the input box, I want that value to be ret ...

Implementing a 'Load More' button for a list in Vue.js

I am currently working on adding a load more button to my code. While I could achieve this using JavaScript, I am facing difficulties implementing it in Vue.js. Here is the Vue code I have been working with. I attempted to target the element with the compa ...

Issues with Gulp and Browser Sync integration

Encountering errors while running Gulp with Browser Sync in Chrome: NonESPMessageInterface --- nonEspMessageInterface.js:8 TypeError: Cannot read property 'insertBefore' of null --- angular.js:13708 Checklist message was invalid, from origin # ...

How can I recreate this image in 3D using three.js?

I have a tower image' - but i don't know how to replicate this for3dview using thethree.js` any assistance would be greatly appreciated! Here is the image : This is my attempt : $(function () { "use strict"; var container, scene, cam ...

Ensure that each item rendered in a VUE.js v-for loop is distinct and not repetitive

I have obtained a JSON formatted object from a Web API that contains information about NIH funding grants. Each grant provides a history of awards for a specific researcher. My goal is to display only the latest award_notice_date for each unique project ...

jQuery: Locate and eliminate any images in the text that appear after a specific group of tags if no images are present

Currently, I am in the process of developing a feed reader specifically designed to parse the Google News Feed. You can view and test the code on this Fiddle. My main challenge lies in removing titles and sources from the descriptions. Through my explorati ...

Why might the Bootstrap menu be malfunctioning?

The reality is that Bootstrap is functional and widely used. Sharing the code could make a big difference in getting assistance! <ul class="top-header-contact-info secondary-menu"> <li class="nav-item dropdown-toggle"> ...

Modifying the Position of the Search Box within DataTables by Manipulating DOM Elements

As a newcomer to the jQuery datatables plugin, I am still learning how to use it effectively. I have connected the plugin to my tables using the following code: $(document).ready(function() $('#table_id').dataTable({ }); }); ...

Launch target _blank within a modal instead of a new tab

I'm currently exploring ways to use vanilla JavaScript in order to display all external links - particularly those that typically open in a new tab or window - within a modal box instead. My goal is to implement a listener on external links (those no ...

When traversing across different child elements, the MouseEvent.offsetX/Y values get reset to 0

Check out this interactive example. The demonstration includes a main div with 3 child divs. A click event is triggered on the main div, but instead of displaying alerts with the mouse position relative to the parent div as expected, it shows the position ...