¿Cómo obtener el seguimiento de la pila de JavaScript cuando se lanza una excepción?

El seguimiento de la pila es un método estable para identificar el error que se produce en el programa cuando se llama a la función de ese programa. Ayuda a los programadores a verificar de dónde viene el error/excepción en particular y cuál es la razón detrás de él. Dependiendo de la hora en que se recopilan los datos de seguimiento, el tamaño del archivo para estos seguimientos puede ser enorme. Tenemos que encontrar una manera de obtener un seguimiento de la pila de JavaScript al generar un error/excepción.

El seguimiento de la pila es un informe de los marcos de pila activos en un momento determinado durante la ejecución de un programa. Cuando el programa se está ejecutando, la memoria a menudo se asigna dinámicamente en la pila y en el montón. La pila es más activa en comparación con el montón porque generalmente es una región continua de memoria que asigna contexto local para cada función en ejecución. Stack también se refiere a la construcción de programación, por lo que esta pila se denomina pila de tiempo de ejecución de un programa. Una vez que se ha asignado un bloque de memoria en la pila. No se puede eliminar fácilmente, ya que puede haber otros bloques de memoria que se asignaron antes. Cada vez que se llama a la función en el programa, se asigna un bloque de memoria en la parte superior de la pila de tiempo de ejecución llamado registro de activación. Los programadores suelen utilizar el seguimiento de pila durante la interacción y la depuración.

Stack es un tipo de estructura de datos donde los datos se pueden almacenar en forma de último en entrar, primero en salir (LIFO) . Significa que la pila es un tipo de almacenamiento y cuando un grupo de datos entra dentro de la pila, se almacena uno por uno de tal manera que los últimos datos se eliminan primero y los primeros datos se eliminan al final. La forma en que cualquier grupo de almacén de datos y eliminación de la pila se puede entender mediante el seguimiento de la pila.
Existen los siguientes métodos mediante los cuales podemos obtener un seguimiento de pila para JavaScript al lanzar una excepción.

  • consola.trace
  • Objeto de error
  • objeto llamador
  • Uso de console.trace: el objeto de la consola también tiene un método llamado método console.trace() , que le brinda el seguimiento en la consola. Cada vez que se llama, se genera un seguimiento de pila para la función. Podemos entender esto con la ayuda de este ejemplo.

    • Programa:

      // Sum function
      function sum(a, b) {
          console.trace('sum called with ', a, 'and', b);
          return a+b;
      }
        
      // Calculation function 
      function calc() {
          return sum(8, 11) + sum(9, 14);
      }
        
      // Start function
      function start() {
          var a = sum(2, 3);
          var b = calc();
      }
         
      // Calling start function 
      start();
    • Producción:
      /usr/bin/node stacktrace.js
      Trace: add called with  2 and 3
          at sum (/home/dev/Documents/stacktrace.js:2:13)
          at start (/home/dev/Documents/stacktrace.js:11:13)
          at Object. (/home/dev/Documents/stacktrace.js:16:1)
          at Module._compile (internal/modules/cjs/loader.js:959:30)
          at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
          at Module.load (internal/modules/cjs/loader.js:815:32)
          at Function.Module._load (internal/modules/cjs/loader.js:727:14)
          at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
          at internal/main/run_main_module.js:17:11
      Trace: add called with  8 and 11
          at sum (/home/dev/Documents/stacktrace.js:2:13)
          at calc (/home/dev/Documents/stacktrace.js:7:12)
          at start (/home/dev/Documents/stacktrace.js:12:13)
          at Object. (/home/dev/Documents/stacktrace.js:16:1)
          at Module._compile (internal/modules/cjs/loader.js:959:30)
          at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
          at Module.load (internal/modules/cjs/loader.js:815:32)
          at Function.Module._load (internal/modules/cjs/loader.js:727:14)
          at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
          at internal/main/run_main_module.js:17:11
      Trace: add called with  9 and 14
          at sum (/home/dev/Documents/stacktrace.js:2:13)
          at calc (/home/dev/Documents/stacktrace.js:7:25)
          at start (/home/dev/Documents/stacktrace.js:12:13)
          at Object. (/home/dev/Documents/stacktrace.js:16:1)
          at Module._compile (internal/modules/cjs/loader.js:959:30)
          at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
          at Module.load (internal/modules/cjs/loader.js:815:32)
          at Function.Module._load (internal/modules/cjs/loader.js:727:14)
          at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
          at internal/main/run_main_module.js:17:11
      

    Usando el objeto de error: podemos crear un objeto de error y devolver el atributo de pila . Una propiedad de pila no estándar del objeto Error le brinda el seguimiento de la pila cuando se llamó a esa función en particular desde qué línea y archivo, y con qué argumentos. La string de la pila procede de las llamadas más recientes a las anteriores.

  • Programa:

    // Sum function
    function sum(a, b) {
        console.log(new Error().stack);
        return a+b;
    }
      
    // Calculation function 
    function calc() {
        return sum(8, 11) + sum(9, 14);
    }
      
    // Start function 
    function start() {
        var a = sum(2, 3);
        var b = calc();
    }
       
    // Calling start function 
    start();
  • Producción:
    /usr/bin/node trace.js
    Error
        at sum (/home/dev/Documents/trace.js:2:17)
        at start (/home/dev/Documents/trace.js:11:13)
        at Object. (/home/dev/Documents/trace.js:16:1)
        at Module._compile (internal/modules/cjs/loader.js:959:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
        at Module.load (internal/modules/cjs/loader.js:815:32)
        at Function.Module._load (internal/modules/cjs/loader.js:727:14)
        at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
        at internal/main/run_main_module.js:17:11
    Error
        at sum (/home/dev/Documents/trace.js:2:17)
        at calc (/home/dev/Documents/trace.js:7:12)
        at start (/home/dev/Documents/trace.js:12:13)
        at Object. (/home/dev/Documents/trace.js:16:1)
        at Module._compile (internal/modules/cjs/loader.js:959:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
        at Module.load (internal/modules/cjs/loader.js:815:32)
        at Function.Module._load (internal/modules/cjs/loader.js:727:14)
        at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
        at internal/main/run_main_module.js:17:11
    Error
        at sum (/home/dev/Documents/trace.js:2:17)
        at calc (/home/dev/Documents/trace.js:7:25)
        at start (/home/dev/Documents/trace.js:12:13)
        at Object. (/home/dev/Documents/trace.js:16:1)
        at Module._compile (internal/modules/cjs/loader.js:959:30)
        at Object.Module._extensions..js (internal/modules/cjs/loader.js:995:10)
        at Module.load (internal/modules/cjs/loader.js:815:32)
        at Function.Module._load (internal/modules/cjs/loader.js:727:14)
        at Function.Module.runMain (internal/modules/cjs/loader.js:1047:10)
        at internal/main/run_main_module.js:17:11
    
  • Uso del objeto llamador: hemos implementado una función llamada stacktrace que devolverá una string que representa el historial de llamadas hasta el punto donde se llamó a stacktrace() . Internamente, utiliza otra función llamada st2 que se llamará recursivamente atravesando el árbol de llamadas hasta el punto en el que llegamos al cuerpo principal de nuestro script JavaScript. Al final de la declaración de stacktrace, llamamos a st2 con arguments.callee.caller . arguments es un objeto especial que pertenece a la llamada de función actual y que contiene mucha información sobre la llamada actual. Luego, se llama recursivamente a la función st2 y devuelve la string stacktrace hasta el momento.

    • Programa:

      // Sum function
      function sum(a,b) {
         
          // Calling stacktrace function
          console.log(stacktrace()); 
          return a+b;
      }
         
      // Calculation function 
      function calc() {
          return sum(8, 11) + sum(9, 14);
      }
         
      // Start function 
      function start() {
          var a = sum(2, 3);
          var b = calc();
      }
          
      // Calling start function 
      start();
         
      // Stacktrace function 
      function stacktrace() {
        function st2(f) {
          var args = [];
          if (f) {
              for (var i = 0; i < f.arguments.length; i++) {
                  args.push(f.arguments[i]);
              }
              var function_name = f.toString().
              split('(')[0].substring(9);
              return st2(f.caller) + function_name + 
              '(' + args.join(', ') + ')' + "\n";
          } else {
              return "";
          }
        }
        return st2(arguments.callee.caller);
      }
    • Producción:
      /usr/bin/node stackt.js
      ([object Object], function require(path) {
            return mod.require(path);
          }, [object Object], /home/dev/Documents/stackt.js, /home/dev/Documents)
      start()
      sum(2, 3)
      ([object Object], function require(path) {
            return mod.require(path);
          }, [object Object], /home/dev/Documents/stackt.js, /home/dev/Documents)
      start()
      calc()
      sum(8, 11)
      ([object Object], function require(path) {
            return mod.require(path);
          }, [object Object], /home/dev/Documents/stackt.js, /home/dev/Documents)
      start()
      calc()
      sum(9, 14)
      

    Publicación traducida automáticamente

    Artículo escrito por iamdev_ y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *