Permalink
Browse files

Don't prematurely exit, ever

I think this is why the npm cache gets corrupted so often.
If there's a failure while another package is in the process
of downloading, then it'll result in a corrupted tarball.

Instead, just set the exitCode, and only actually exit with
tht code when the 'exit' event occurs, so that in-transit
jobs are not forcibly killed.
  • Loading branch information...
1 parent 2d2418f commit 31e4d8afdee6c83043d89182b6cdb767f8303d21 @isaacs isaacs committed Jun 4, 2012
Showing with 34 additions and 19 deletions.
  1. +34 −19 lib/utils/error-handler.js
View
53 lib/utils/error-handler.js
@@ -10,13 +10,14 @@ var cbCalled = false
, path = require("path")
, ini = require("./ini.js")
, wroteLogFile = false
+ , exitCode = 0
process.on("exit", function (code) {
// console.error("exit", code)
if (!ini.resolved) return
if (code) itWorked = false
- if (itWorked) log("ok")
+ if (itWorked) log.info("ok")
else {
if (!cbCalled) {
log.error("cb() never called!\n ")
@@ -30,9 +31,40 @@ process.on("exit", function (code) {
}
log.win("not ok")
}
- itWorked = false // ready for next exit
+
+ var doExit = npm.config.get("_exit")
+ if (doExit) {
+ // actually exit.
+ if (exitCode === 0 && !itWorked) {
+ exitCode = 1
+ }
+ if (exitCode !== 0) process.exit(exitCode)
+ } else {
+ itWorked = false // ready for next exit
+ }
})
+function exit (code, noLog) {
+ exitCode = exitCode || code
+
+ var doExit = npm.config.get("_exit")
+ log.verbose([code, doExit], "exit")
+ if (log.level === log.LEVEL.silent) noLog = true
+
+ if (code && !noLog) writeLogFile(reallyExit)
+ else rm("npm-debug.log", function () { rm(npm.tmp, reallyExit) })
+
+ function reallyExit() {
+ itWorked = !code
+
+ // just emit a fake exit event.
+ // if we're really exiting, then let it exit on its own, so that
+ // in-process stuff can finish or clean up first.
+ if (!doExit) process.emit("exit", code)
+ }
+}
+
+
function errorHandler (er) {
// console.error("errorHandler", er)
if (!ini.resolved) {
@@ -222,23 +254,6 @@ function errorHandler (er) {
exit(typeof er.errno === "number" ? er.errno : 1)
}
-function exit (code, noLog) {
- var doExit = npm.config.get("_exit")
- log.verbose([code, doExit], "exit")
- if (log.level === log.LEVEL.silent) noLog = true
-
- if (code && !noLog) writeLogFile(reallyExit)
- else rm("npm-debug.log", function () { rm(npm.tmp, reallyExit) })
-
- function reallyExit() {
- itWorked = !code
- //if (!itWorked) {
- if (!doExit) process.emit("exit", code)
- else process.exit(code)
- //}
- }
-}
-
var writingLogFile = false
function writeLogFile (cb) {
if (writingLogFile) return cb()

1 comment on commit 31e4d8a

@domenic
npm member

Nice!

Please sign in to comment.