Saltar al contenido

¿Cómo depuro “Error: spawn ENOENT” en node.js?

Solución:

NOTA: Este error casi siempre se debe a que el comando no existe, a que el directorio de trabajo no existe oa un error exclusivo de Windows.

Encontré una manera fácil y particular de tener una idea de la causa raíz de:

Error: spawn ENOENT

El problema de este error es que hay muy poca información en el mensaje de error para decirle dónde está el sitio de la llamada, es decir, qué ejecutable / comando no se encuentra, especialmente cuando tiene una base de código grande donde hay muchas llamadas de generación. . Por otro lado, si conocemos el comando exacto que causa el error, podemos seguir la respuesta de @laconbass para solucionar el problema.

Encontré una manera muy fácil de detectar qué comando causa el problema en lugar de agregar detectores de eventos en todas partes en su código como se sugiere en la respuesta de @laconbass. La idea clave es envolver la llamada de generación original con un contenedor que imprima los argumentos enviados a la llamada de generación.

Aquí está la función de envoltura, colóquela en la parte superior de la index.js o cualquiera que sea el script de inicio de su servidor.

(function() {
    var childProcess = require("child_process");
    var oldSpawn = childProcess.spawn;
    function mySpawn() {
        console.log('spawn called');
        console.log(arguments);
        var result = oldSpawn.apply(this, arguments);
        return result;
    }
    childProcess.spawn = mySpawn;
})();

Luego, la próxima vez que ejecute su aplicación, antes del mensaje de excepción no detectada, verá algo así:

spawn called
{ '0': 'hg',
  '1': [],
  '2':
   { cwd: '/* omitted */',
     env: { IP: '0.0.0.0' },
     args: [] } }

De esta manera, puede saber fácilmente qué comando se ejecuta realmente y luego puede averiguar por qué nodejs no puede encontrar el ejecutable para solucionar el problema.

Paso 1: asegúrese spawn se llama de la manera correcta

Primero, revise los documentos de child_process.spawn (comando, argumentos, opciones):

Lanza un nuevo proceso con lo dado command, con argumentos de línea de comando en args. Si se omite, args por defecto es una matriz vacía.

El tercer argumento se utiliza para especificar opciones adicionales, cuyo valor predeterminado es:

{ cwd: undefined, env: process.env }

Usar env para especificar las variables de entorno que serán visibles para el nuevo proceso, el valor predeterminado es process.env.

Asegúrese de no poner ningún argumento de línea de comando en command y todo spawn la llamada es válida. Continúe con el paso siguiente.

Paso 2: identificar el emisor de eventos que emite el evento de error

Busque en su código fuente para cada llamada a spawn, o child_process.spawn, es decir

spawn('some-command', [ '--help' ]);

y adjunte allí un detector de eventos para el evento ‘error’, para que se dé cuenta del Emisor de eventos exacto que lo lanza como ‘No controlado’. Después de la depuración, ese controlador se puede eliminar.

spawn('some-command', [ '--help' ])
  .on('error', function( err ){ throw err })
;

Ejecute y debería obtener la ruta del archivo y el número de línea donde se registró su oyente de ‘error’. Algo como:

/file/that/registers/the/error/listener.js:29
      throw err;
            ^
Error: spawn ENOENT
    at errnoException (child_process.js:1000:11)
    at Process.ChildProcess._handle.onexit (child_process.js:791:34)

Si las dos primeras líneas siguen

events.js:72
        throw er; // Unhandled 'error' event

repita este paso hasta que no lo estén. Debe identificar el oyente que emite el error antes de continuar con el siguiente paso.

Paso 3: asegúrese de la variable de entorno $PATH Está establecido

Hay dos escenarios posibles:

  1. Confías en lo predeterminado spawn comportamiento, por lo que el entorno del proceso hijo será el mismo que process.env.
  2. Estás pasando explícitamente un env oponerse a spawn sobre el options argumento.

En ambos escenarios, debe inspeccionar el PATH clave en el objeto de entorno que utilizará el proceso hijo generado.

Ejemplo para el escenario 1

// inspect the PATH key on process.env
console.log( process.env.PATH );
spawn('some-command', ['--help']);

Ejemplo para el escenario 2

var env = getEnvKeyValuePairsSomeHow();
// inspect the PATH key on the env object
console.log( env.PATH );
spawn('some-command', ['--help'], { env: env });

La ausencia de PATH (es decir, es undefined) causará spawn para emitir el ENOENT error, ya que no será posible localizar ninguna command a menos que sea una ruta absoluta al archivo ejecutable.

Cuando PATH está configurado correctamente, continúe con el paso siguiente. Debe ser un directorio o una lista de directorios. El último caso es el habitual.

Paso 4: asegúrese command existe en un directorio de los definidos en PATH

El engendro puede emitir el ENOENT error si el nombre del archivo command (es decir, ‘algún comando’) no existe en al menos uno de los directorios definidos en PATH.

Localice el lugar exacto de command. En la mayoría de las distribuciones de Linux, esto se puede hacer desde una terminal con la which mando. Le dirá la ruta absoluta al archivo ejecutable (como arriba), o le dirá si no se encuentra.

Ejemplo de uso de which y su salida cuando un comando es fundar

> which some-command
some-command is /usr/bin/some-command

Ejemplo de uso de which y su salida cuando un comando es extraviado

> which some-command
bash: type: some-command: not found

Los programas mal instalados son la causa más común de extraviado mando. Consulte la documentación de cada comando si es necesario e instálelo.

Cuando el comando es un archivo de secuencia de comandos simple, asegúrese de que sea accesible desde un directorio en el PATH. Si no es así, muévalo a uno o cree un enlace a él.

Una vez que determine PATH está configurado correctamente y command es accesible desde él, debería poder generar su proceso hijo sin spawn ENOENT siendo arrojado.

Como lo señaló @DanielImfeld, se lanzará ENOENT si especifica “cwd” en las opciones, pero el directorio dado no existe.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

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