nodejs / nodejs/node

error handler of same domain can be called several times when it throws

Abierto
#25,505 3 comentarios 0 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

domain help wanted
Lenguaje dominante
JavaScript
Estrellas
122k
Forks
37.4k
Merge medio
4 d 2 h
PR fusionados (30 d)
283

Descripción

  • Version: Current tip of master (66f45e7e5b), but probably applies to all versions.
  • Platform: All platforms.
  • Subsystem: domain.

The following code:

'use strict';

const common = require('../common');
const domain = require('domain');
const http = require('http');

const server = http.createServer((req, res) => {
  res.end();
});

let numDomainErrorListenerCalls = 0;

function performHttpRequestWithDomain(cb) {
  const d = domain.create();
  d.run(() => {
    const req = http.get({
      host: '127.0.0.1', port: server.address().port
    }, (res) => {
      res.on('data', () => {});
      res.on('end', () => {
        throw new Error('bang');
      });
    });

    req.end();
  });

  d.on('error', (domainErr) => {
    console.log(++numDomainErrorListenerCalls);
    throw new Error('boom');
  });
}

server.listen(0, '127.0.0.1', () => {
  performHttpRequestWithDomain(common.mustCall(() => {
    server.close();
  }));
});

gives the following output:

$ ./node test/parallel/test-http-req-domain-stack.js 
1
2
/Users/jgilli/dev/node/test/parallel/test-http-req-domain-stack.js:30
    throw new Error('boom');
    ^

Error: boom
    at Domain.d.on (/Users/jgilli/dev/node/test/parallel/test-http-req-domain-stack.js:30:11)
    at Domain.emit (events.js:188:13)
    at Domain.EventEmitter.emit (domain.js:430:20)
    at Domain._errorHandler (domain.js:216:23)
    at Domain._errorHandler (domain.js:244:33)
    at Object.setUncaughtExceptionCaptureCallback (domain.js:132:29)
    at process._fatalException (internal/process/execution.js:102:29)

The uncaught exception is expected. What is not expected as far as I understand is for the same domain's error handler to run more than once.

I believe the original intention of the domain's implementation is to pop the domains stack when a domain's error handler throw, so that the domain that handles that new error is the "parent" domain.

However, in the example above the same domain is pushed on the stack more than once. For instance, when an event is emitted from a nextTick callback, the same domain will be entered from the nextTick callbacks scheduler and then once again from the event emitter.

Pushing the same domain on the stack more than once makes sense so that the components that push a domain can pop it from the stack. However, I think we could probably replace the call to pop the stack once in the domain error handling code to remove all consecutive instances of that domain instead.

@nodejs/domains Thoughts?

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con test/parallel/test-http-req-domain-stack.js y reproduce las llamadas repetidas al listener de errores. Lee lib/domain.js junto con internal/process/next_tick.js, especialmente las rutas de gestión de la pila referenciadas. Se considera terminado cuando la regresión está cubierta y el controlador de errores del mismo domain deja de llamarse repetidamente cuando lanza una excepción.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
javascript, nodejs
Área
backend, testing
Tipo de issue
Error
Dificultad
4/5
Tiempo estimado
3-5 días
Estado de actividad
Tranquilo
Claridad
Bastante claro
Aptitud para principiantes
48/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.