Skip to content

Bun habla el Protocolo Inspector de WebKit, por lo que puedes depurar tu código con un depurador interactivo. Para fines de demostración, considera el siguiente servidor web simple.

Depuración de JavaScript y TypeScript

typescript
Bun.serve({
  fetch(req) {
    console.log(req.url);
    return new Response("Hello, world!");
  },
});

--inspect

Para habilitar la depuración al ejecutar código con Bun, usa la bandera --inspect. Esto inicia automáticamente un servidor WebSocket en un puerto disponible que se puede usar para inspeccionar el proceso de Bun en ejecución.

sh
bun --inspect server.ts
txt
------------------ Inspector de Bun ------------------
Escuchando en:
  ws://localhost:6499/0tqxs9exrgrm

Inspecciona en el navegador:
  https://debug.bun.sh/#localhost:6499/0tqxs9exrgrm
------------------ Inspector de Bun ------------------

--inspect-brk

La bandera --inspect-brk se comporta idénticamente a --inspect, excepto que automáticamente inyecta un punto de interrupción en la primera línea del script ejecutado. Esto es útil para depurar scripts que se ejecutan rápidamente y salen inmediatamente.

--inspect-wait

La bandera --inspect-wait se comporta idénticamente a --inspect, excepto que el código no se ejecutará hasta que un depurador se haya adjuntado al proceso en ejecución.

Establecer un puerto o URL para el depurador

Independientemente de qué bandera uses, opcionalmente puedes especificar un número de puerto, prefijo de URL, o ambos.

sh
bun --inspect=4000 server.ts
bun --inspect=localhost:4000 server.ts
bun --inspect=localhost:4000/prefix server.ts

Depuradores

Varias herramientas de depuración pueden conectarse a este servidor para proporcionar una experiencia de depuración interactiva.

debug.bun.sh

Bun aloja un depurador basado en web en debug.bun.sh. Es una versión modificada de la Interfaz Web Inspector de WebKit, que resultará familiar a los usuarios de Safari.

Abre la URL debug.bun.sh proporcionada en tu navegador para iniciar una sesión de depuración. Desde esta interfaz, podrás ver el código fuente del archivo en ejecución, ver y establecer puntos de interrupción, y ejecutar código con la consola integrada.

Establezcamos un punto de interrupción. Navega a la pestaña Sources (Fuentes); deberías ver el código de antes. Haz clic en el número de línea 3 para establecer un punto de interrupción en nuestra declaración console.log(req.url).

Luego visita http://localhost:3000 en tu navegador web. Esto enviará una solicitud HTTP a nuestro servidor web localhost. Parecerá que la página no está cargando. ¿Por qué? Porque el programa ha pausado la ejecución en el punto de interrupción que establecimos antes.

Nota cómo ha cambiado la interfaz de usuario.

En este punto hay mucho que podemos hacer para inspeccionar el entorno de ejecución actual. Podemos usar la consola en la parte inferior para ejecutar código arbitrario en el contexto del programa, con acceso completo a las variables en scope en nuestro punto de interrupción.

En el lado derecho del panel Sources, podemos ver todas las variables locales actualmente en scope, y profundizar para ver sus propiedades y métodos. Aquí, estamos inspeccionando la variable req.

En la parte superior izquierda del panel Sources, podemos controlar la ejecución del programa.

Aquí hay una hoja de trucos que explica las funciones de los botones de control de flujo.

  • Continuar ejecución del script — continuar ejecutando el programa hasta el siguiente punto de interrupción o excepción.
  • Step over (Pasar) — El programa continuará a la siguiente línea.
  • Step into (Entrar) — Si la declaración actual contiene una llamada a función, el depurador "entrará" en la función llamada.
  • Step out (Salir) — Si la declaración actual es una llamada a función, el depurador terminará de ejecutar la llamada, luego "saldrá" de la función a la ubicación donde fue llamada.

Depurador de Visual Studio Code

El soporte experimental para depurar scripts de Bun está disponible en Visual Studio Code. Para usarlo, necesitarás instalar la extensión Bun VSCode.


Depuración de Solicitudes de Red

La variable de entorno BUN_CONFIG_VERBOSE_FETCH te permite registrar solicitudes de red hechas con fetch() o node:http automáticamente.

ValorDescripción
curlImprime solicitudes como comandos curl.
trueImprime información de solicitud y respuesta
falseNo imprime nada. Predeterminado

Imprimir solicitudes fetch y node:http como comandos curl

Bun también soporta imprimir solicitudes de red fetch() y node:http como comandos curl estableciendo la variable de entorno BUN_CONFIG_VERBOSE_FETCH en curl. Esto imprime la solicitud fetch como un comando curl de una sola línea para permitirte copiar y pegar en tu terminal para replicar la solicitud.

ts
process.env.BUN_CONFIG_VERBOSE_FETCH = "curl";

await fetch("https://example.com", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ foo: "bar" }),
});
txt
[fetch] $ curl --http1.1 "https://example.com/" -X POST -H "content-type: application/json" -H "Connection: keep-alive" -H "User-Agent: Bun/1.3.3" -H "Accept: */*" -H "Host: example.com" -H "Accept-Encoding: gzip, deflate, br" --compressed -H "Content-Length: 13" --data-raw "{\"foo\":\"bar\"}"
[fetch] > HTTP/1.1 POST https://example.com/
[fetch] > content-type: application/json
[fetch] > Connection: keep-alive
[fetch] > User-Agent: Bun/1.3.3
[fetch] > Accept: */*
[fetch] > Host: example.com
[fetch] > Accept-Encoding: gzip, deflate, br
[fetch] > Content-Length: 13

[fetch] < 200 OK
[fetch] < Accept-Ranges: bytes
[fetch] < Cache-Control: max-age=604800
[fetch] < Content-Type: text/html; charset=UTF-8
[fetch] < Date: Tue, 18 Jun 2024 05:12:07 GMT
[fetch] < Etag: "3147526947"
[fetch] < Expires: Tue, 25 Jun 2024 05:12:07 GMT
[fetch] < Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
[fetch] < Server: EOS (vny/044F)
[fetch] < Content-Length: 1256

Las líneas con [fetch] > son la solicitud desde tu código local, y las líneas con [fetch] < son la respuesta desde el servidor remoto.

La variable de entorno BUN_CONFIG_VERBOSE_FETCH está soportada tanto en solicitudes fetch() como node:http, por lo que debería funcionar directamente.

Para imprimir sin el comando curl, establece BUN_CONFIG_VERBOSE_FETCH en true.

ts
process.env.BUN_CONFIG_VERBOSE_FETCH = "true";

await fetch("https://example.com", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ foo: "bar" }),
});
txt
[fetch] > HTTP/1.1 POST https://example.com/
[fetch] > content-type: application/json
[fetch] > Connection: keep-alive
[fetch] > User-Agent: Bun/1.3.3
[fetch] > Accept: */*
[fetch] > Host: example.com
[fetch] > Accept-Encoding: gzip, deflate, br
[fetch] > Content-Length: 13

[fetch] < 200 OK
[fetch] < Accept-Ranges: bytes
[fetch] < Cache-Control: max-age=604800
[fetch] < Content-Type: text/html; charset=UTF-8
[fetch] < Date: Tue, 18 Jun 2024 05:12:07 GMT
[fetch] < Etag: "3147526947"
[fetch] < Expires: Tue, 25 Jun 2024 05:12:07 GMT
[fetch] < Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
[fetch] < Server: EOS (vny/044F)
[fetch] < Content-Length: 1256

Stacktraces y sourcemaps

Bun transpila cada archivo, lo que suena como si significara que los stack traces que ves en la consola apuntarían inútilmente a la salida transpilada. Para abordar esto, Bun genera y sirve automáticamente sourcemaps para cada archivo que transpila. Cuando ves un stack trace en la consola, puedes hacer clic en la ruta del archivo y ser llevado al código fuente original, incluso si fue escrito en TypeScript o JSX, o tiene alguna otra transformación aplicada.

Bun carga automáticamente sourcemaps tanto en tiempo de ejecución al transpilar archivos bajo demanda, como al usar bun build para precompilar archivos con anticipación.

Vista previa de código fuente con resaltado de sintaxis

Para ayudar con la depuración, Bun imprime automáticamente una pequeña vista previa del código fuente cuando ocurre una excepción o rechazo no manejado. Puedes simular este comportamiento llamando a Bun.inspect(error):

ts
// Crear un error
const err = new Error("Algo salió mal");
console.log(Bun.inspect(err, { colors: true }));

Esto imprime una vista previa con resaltado de sintaxis del código fuente donde ocurrió el error, junto con el mensaje de error y el stack trace.

ts
1 | // Crear un error
2 | const err = new Error("Algo salió mal");
                ^
error: Algo salió mal
      en file.js:2:13

Stack Traces de V8

Bun usa JavaScriptCore como su motor, pero gran parte del ecosistema de Node.js y npm espera V8. Los motores de JavaScript difieren en el formato de error.stack. Bun tiene la intención de ser un reemplazo directo para Node.js, y eso significa que es nuestro trabajo asegurarnos de que aunque el motor sea diferente, los stack traces sean lo más similares posible.

Es por eso que cuando registras error.stack en Bun, el formato de error.stack es el mismo que en el motor V8 de Node.js. Esto es especialmente útil cuando usas bibliotecas que esperan stack traces de V8.

API de Stack Trace de V8

Bun implementa la API de Stack Trace de V8, que es un conjunto de funciones que te permiten manipular stack traces.

Error.prepareStackTrace

La función Error.prepareStackTrace es una función global que te permite personalizar la salida del stack trace. Esta función se llama con el objeto de error y un array de objetos CallSite y te permite devolver un stack trace personalizado.

ts
Error.prepareStackTrace = (err, stack) => {
  return stack.map(callSite => {
    return callSite.getFileName();
  });
};

const err = new Error("Algo salió mal");
console.log(err.stack);
// [ "error.js" ]

El objeto CallSite tiene los siguientes métodos:

MétodoDevuelve
getThisValor this de la llamada a función
getTypeNametypeof this
getFunctionobjeto función
getFunctionNamenombre de la función como cadena
getMethodNamenombre del método como cadena
getFileNamenombre del archivo o URL
getLineNumbernúmero de línea
getColumnNumbernúmero de columna
getEvalOriginundefined
getScriptNameOrSourceURLURL de origen
isTopleveldevuelve true si la función está en el scope global
isEvaldevuelve true si la función es una llamada eval
isNativedevuelve true si la función es nativa
isConstructordevuelve true si la función es un constructor
isAsyncdevuelve true si la función es async
isPromiseAllNo implementado aún.
getPromiseIndexNo implementado aún.
toStringdevuelve una representación en cadena del sitio de llamada

En algunos casos, el objeto Function puede haber sido recolectado por el garbage collector, por lo que algunos de estos métodos pueden devolver undefined.

Error.captureStackTrace(error, startFn)

La función Error.captureStackTrace te permite capturar un stack trace en un punto específico de tu código, en lugar del punto donde se lanzó el error.

Esto puede ser útil cuando tienes callbacks o código asíncrono que hace difícil determinar dónde se originó un error. El segundo argumento de Error.captureStackTrace es la función donde quieres que comience el stack trace.

Por ejemplo, el siguiente código hará que err.stack apunte al código que llama a fn(), aunque el error se lanzó en myInner.

ts
const fn = () => {
  function myInner() {
    throw err;
  }

  try {
    myInner();
  } catch (err) {
    console.log(err.stack);
    console.log("");
    console.log("-- captureStackTrace --");
    console.log("");
    Error.captureStackTrace(err, fn);
    console.log(err.stack);
  }
};

fn();
txt
Error: ¡aquí!
    at myInner (file.js:4:15)
    at fn (file.js:8:5)
    at module code (file.js:17:1)
    at moduleEvaluation (native)
    at moduleEvaluation (native)
    at <anonymous> (native)

-- captureStackTrace --

Error: ¡aquí!
    at module code (file.js:17:1)
    at moduleEvaluation (native)
    at moduleEvaluation (native)
    at <anonymous> (native)

Bun por www.bunjs.com.cn editar