работает нормально и производит ожидаемый результат вместо любой ошибки времени выполнения.
Это основная ошибка допущения.
Приложение: обратите внимание, что при наличии дефекта CWG ( # 315
Addendum: g0]), который закрывается как «согласованный» , а не , делающий вышеуказанный UB, он полагается на положительное закрытие другого дефекта CWG (
# 232 ), который по-прежнему активен, и, следовательно, ни один из них не добавлен к стандарту.Позвольте мне привести часть комментария из Джеймса Макнеллиса к an ответьте на аналогичный вопрос переполнения стека:
Я не думаю, что дефект CWG 315 «закрыт», поскольку его присутствие на странице «закрытые проблемы» подразумевает. В обосновании говорится, что это должно быть разрешено, потому что «* p не является ошибкой, когда p равно null, если значение lvalue не преобразуется в значение r». Тем не менее, это зависит от концепции «пустой lvalue», которая является частью предлагаемой резолюции для дефекта CWG 232, но которая не была принята.
Вы можете зарегистрировать обработчик для process.on('exit')
и в любом другом случае (SIGINT
или необработанное исключение) для вызова process.exit()
process.stdin.resume();//so the program will not close instantly
function exitHandler(options, exitCode) {
if (options.cleanup) console.log('clean');
if (exitCode || exitCode === 0) console.log(exitCode);
if (options.exit) process.exit();
}
//do something when app is closing
process.on('exit', exitHandler.bind(null,{cleanup:true}));
//catches ctrl+c event
process.on('SIGINT', exitHandler.bind(null, {exit:true}));
// catches "kill pid" (for example: nodemon restart)
process.on('SIGUSR1', exitHandler.bind(null, {exit:true}));
process.on('SIGUSR2', exitHandler.bind(null, {exit:true}));
//catches uncaught exceptions
process.on('uncaughtException', exitHandler.bind(null, {exit:true}));
function fnAsyncTest(callback) {
require('fs').writeFile('async.txt', 'bye!', callback);
}
function fnSyncTest() {
for (var i = 0; i < 10; i++) {}
}
function killProcess() {
if (process.exitTimeoutId) {
return;
}
process.exitTimeoutId = setTimeout(process.exit, 5000);
console.log('process will exit in 5 seconds');
fnAsyncTest(function() {
console.log('async op. done', arguments);
});
if (!fnSyncTest()) {
console.log('sync op. done');
}
}
// https://nodejs.org/api/process.html#process_signal_events
process.on('SIGTERM', killProcess);
process.on('SIGINT', killProcess);
process.on('uncaughtException', function(e) {
console.log('[uncaughtException] app will be terminated: ', e.stack);
killProcess();
/**
* @https://nodejs.org/api/process.html#process_event_uncaughtexception
*
* 'uncaughtException' should be used to perform synchronous cleanup before shutting down the process.
* It is not safe to resume normal operation after 'uncaughtException'.
* If you do use it, restart your application after every unhandled exception!
*
* You have been warned.
*/
});
console.log('App is running...');
console.log('Try to press CTRL+C or SIGNAL the process with PID: ', process.pid);
process.stdin.resume();
// just for testing
Просто хотел упомянуть пакет death
: https://github.com/jprichardson/node-death
Пример:
var ON_DEATH = require('death')({uncaughtException: true}); //this is intentionally ugly
ON_DEATH(function(signal, err) {
//clean up code here
})
io.js имеет событие exit
и beforeExit
, которые делают то, что вы хотите.
В случае, когда процесс был порожден другим процессом узла, например:
var child = spawn('gulp', ['watch'], {
stdio: 'inherit',
});
И вы пытаетесь его убить позже, через:
child.kill();
Это как вы обрабатываете событие [у ребенка]:
process.on('SIGTERM', function() {
console.log('Goodbye!');
});
Это улавливает каждое событие выхода, которое я могу найти, которое можно обработать. До сих пор кажется довольно надежным и чистым.
[`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`, `SIGTERM`].forEach((eventType) => {
process.on(eventType, cleanUpServer.bind(null, eventType));
})
Нижеприведенный сценарий позволяет иметь один обработчик для всех условий выхода. Он использует специальную функцию обратного вызова для выполнения пользовательского кода очистки.
cleanup.js
// Object to capture process exits and call app specific cleanup function
function noOp() {};
exports.Cleanup = function Cleanup(callback) {
// attach user callback to the process event emitter
// if no callback, it will still exit gracefully on Ctrl-C
callback = callback || noOp;
process.on('cleanup',callback);
// do app specific cleaning before exiting
process.on('exit', function () {
process.emit('cleanup');
});
// catch ctrl+c event and exit normally
process.on('SIGINT', function () {
console.log('Ctrl-C...');
process.exit(2);
});
//catch uncaught exceptions, trace, then exit normally
process.on('uncaughtException', function(e) {
console.log('Uncaught Exception...');
console.log(e.stack);
process.exit(99);
});
};
Этот код перехватывает неперехваченные исключения, Ctrl-C и обычные события выхода. Затем он вызывает одну необязательную функцию обратного вызова очистки пользователя перед ее выходом, обрабатывая все условия выхода с помощью одного объекта.
Модуль просто расширяет объект процесса, а не определяет другой эмитент событий. Без специального обратного вызова приложения очистка по умолчанию не имеет функции op. Этого было достаточно для моего использования, когда дочерние процессы оставались включенными при выходе из Ctrl-C.
Вы можете легко добавить другие события выхода, такие как SIGHUP, по желанию. Примечание: в руководстве NodeJS SIGKILL не может иметь слушателя. В приведенном ниже тестовом коде показаны различные способы использования cleanup.js
// test cleanup.js on version 0.10.21
// loads module and registers app specific cleanup callback...
var cleanup = require('./cleanup').Cleanup(myCleanup);
//var cleanup = require('./cleanup').Cleanup(); // will call noOp
// defines app specific callback...
function myCleanup() {
console.log('App specific cleanup code...');
};
// All of the following code is only needed for test demo
// Prevents the program from closing instantly
process.stdin.resume();
// Emits an uncaught exception when called because module does not exist
function error() {
console.log('error');
var x = require('');
};
// Try each of the following one at a time:
// Uncomment the next line to test exiting on an uncaught exception
//setTimeout(error,2000);
// Uncomment the next line to test exiting normally
//setTimeout(function(){process.exit(3)}, 2000);
// Type Ctrl-C to test forced exit
process.exit()
. У обработчиков очистки теперь есть возможность вести себя как функция кода выхода или сигнала, а обработчики очистки могут быть удалены, если необходимо, для поддержки асинхронной очистки или предотвращения циклической очистки. Теперь он мало похож на приведенный выше код.
– Joe Lapp
27 December 2016 в 06:28
«exit» - событие, которое запускается, когда узел завершает цикл события внутри, он не запускается, когда вы завершаете процесс извне.
То, что вы ищете, выполняет что-то на SIGINT.
Документы в http://nodejs.org/api/process.html#process_signal_events приводят пример:
Пример прослушивания SIGINT:
// Start reading from stdin so we don't exit.
process.stdin.resume();
process.on('SIGINT', function () {
console.log('Got SIGINT. Press Control-D to exit.');
});
Примечание: это, кажется, прерывает сигмин, и вам нужно будет вызвать process.exit (), когда вы закончите с кодом.
kill -2
, будет передан код SIGINT
. Мы должны сделать это так, потому что у нас есть ведение журнала узла в txt-файле, поэтому Ctrl + C невозможно.
– Aust
15 February 2013 в 01:22
must only
выполняете операцииsynchronous
в обработчикеexit
– Lewis 10 February 2015 в 15:23stderr
для нескольких обработчиков очистки. Я написал модуль, который делает все это, github.com/jtlapp/node-cleanup , первоначально основанный на решении cleanup.js ниже, но сильно переработанный на основе обратной связи. Надеюсь, это окажется полезным. – Joe Lapp 27 December 2016 в 06:45