mirror of https://github.com/lukechilds/node.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
265 lines
7.6 KiB
265 lines
7.6 KiB
13 years ago
|
|
||
|
module.exports = errorHandler
|
||
|
|
||
|
var cbCalled = false
|
||
|
, log = require("./log.js")
|
||
|
, npm = require("../npm.js")
|
||
|
, rm = require("rimraf")
|
||
|
, constants = require("constants")
|
||
|
, itWorked = false
|
||
|
, path = require("path")
|
||
|
, ini = require("./ini.js")
|
||
|
, wroteLogFile = false
|
||
|
|
||
|
|
||
|
process.on("exit", function (code) {
|
||
|
// console.error("exit", code)
|
||
|
if (!ini.resolved) return
|
||
|
if (code) itWorked = false
|
||
|
if (itWorked) log("ok")
|
||
|
else {
|
||
|
if (!cbCalled) {
|
||
|
log.error("cb() never called!\n ")
|
||
|
}
|
||
|
if (wroteLogFile) {
|
||
|
log.error([""
|
||
|
,"Additional logging details can be found in:"
|
||
|
," " + path.resolve("npm-debug.log")
|
||
|
].join("\n"))
|
||
|
wroteLogFile = false
|
||
|
}
|
||
|
log.win("not ok")
|
||
|
}
|
||
|
itWorked = false // ready for next exit
|
||
|
})
|
||
|
|
||
|
function errorHandler (er) {
|
||
|
// console.error("errorHandler", er)
|
||
|
if (!ini.resolved) {
|
||
|
// logging won't work unless we pretend that it's ready
|
||
|
er = er || new Error("Exit prior to config file resolving.")
|
||
|
console.error(er.stack || er.message)
|
||
|
}
|
||
|
|
||
|
if (cbCalled) {
|
||
|
er = er || new Error("Callback called more than once.")
|
||
|
}
|
||
|
|
||
|
cbCalled = true
|
||
|
if (!er) return exit(0)
|
||
|
if (!(er instanceof Error)) {
|
||
|
log.error(er)
|
||
|
return exit(1, true)
|
||
|
}
|
||
|
|
||
|
var m = er.code || er.message.match(/^(?:Error: )?(E[A-Z]+)/)
|
||
|
if (m) {
|
||
|
m = m[1]
|
||
|
if (!constants[m] && !npm[m]) constants[m] = {}
|
||
|
er.errno = npm[m] || constants[m]
|
||
|
}
|
||
|
|
||
|
switch (er.errno) {
|
||
|
case "ECONNREFUSED":
|
||
|
case constants.ECONNREFUSED:
|
||
|
log.error(er)
|
||
|
log.error(["If you are using Cygwin, please set up your /etc/resolv.conf"
|
||
|
,"See step 4 in this wiki page:"
|
||
|
," http://github.com/ry/node/wiki/Building-node.js-on-Cygwin-%28Windows%29"
|
||
|
,"If you are not using Cygwin, please report this"
|
||
|
,"at <http://github.com/isaacs/npm/issues>"
|
||
|
,"or email it to <npm-@googlegroups.com>"
|
||
|
].join("\n"))
|
||
|
break
|
||
|
|
||
|
case "EACCES":
|
||
|
case "EPERM":
|
||
|
case constants.EACCES:
|
||
|
case constants.EPERM:
|
||
|
log.error(er)
|
||
|
log.error(["",
|
||
|
"Please use 'sudo' or log in as root to run this command."
|
||
|
,""
|
||
|
," sudo npm "
|
||
|
+npm.config.get("argv").original.map(JSON.stringify).join(" ")
|
||
|
,""
|
||
|
,"or set the 'unsafe-perm' config var to true."
|
||
|
,""
|
||
|
," npm config set unsafe-perm true"
|
||
|
].join("\n"))
|
||
|
break
|
||
|
|
||
|
case npm.ELIFECYCLE:
|
||
|
er.code = "ELIFECYCLE"
|
||
|
log.error(er.message)
|
||
|
log.error(["","Failed at the "+er.pkgid+" "+er.stage+" script."
|
||
|
,"This is most likely a problem with the "+er.pkgname+" package,"
|
||
|
,"not with npm itself."
|
||
|
,"Tell the author that this fails on your system:"
|
||
|
," "+er.script
|
||
|
,"You can get their info via:"
|
||
|
," npm owner ls "+er.pkgname
|
||
|
,"There is likely additional logging output above."
|
||
|
].join("\n"))
|
||
|
break
|
||
|
|
||
|
case npm.EJSONPARSE:
|
||
|
er.code = "EJSONPARSE"
|
||
|
log.error(er.message)
|
||
|
log.error("File: "+er.file)
|
||
|
log.error(["Failed to parse package.json data."
|
||
|
,"package.json must be actual JSON, not just JavaScript."
|
||
|
,"","This is not a bug in npm."
|
||
|
,"Tell the package author to fix their package.json file."
|
||
|
].join("\n"), "JSON.parse")
|
||
|
break
|
||
|
|
||
|
case npm.E404:
|
||
|
er.code = "E404"
|
||
|
if (er.pkgid && er.pkgid !== "-") {
|
||
|
var msg = ["'"+er.pkgid+"' is not in the npm registry."
|
||
|
,"You could maybe bug the author to publish it"]
|
||
|
if (er.pkgid.match(/^node[\.\-]|[\.\-]js$/)) {
|
||
|
var s = er.pkgid.replace(/^node[\.\-]|[\.\-]js$/g, "")
|
||
|
if (s !== er.pkgid) {
|
||
|
s = s.replace(/[^a-z0-9]/g, ' ')
|
||
|
msg.push("Maybe try 'npm search " + s + "'")
|
||
|
}
|
||
|
}
|
||
|
msg.push("Note that you can also install from a tarball or folder.")
|
||
|
log.error(msg.join("\n"), "404")
|
||
|
}
|
||
|
break
|
||
|
|
||
|
case npm.EPUBLISHCONFLICT:
|
||
|
er.code = "EPUBLISHCONFLICT"
|
||
|
log.error(["Cannot publish over existing version."
|
||
|
,"Bump the 'version' field, set the --force flag, or"
|
||
|
," npm unpublish '"+er.pkgid+"'"
|
||
|
,"and try again"
|
||
|
].join("\n"), "publish fail" )
|
||
|
break
|
||
|
|
||
|
case npm.EISGIT:
|
||
|
er.code = "EISGIT"
|
||
|
log.error([er.message
|
||
|
," "+er.path
|
||
|
,"Refusing to remove it. Update manually,"
|
||
|
,"or move it out of the way first."
|
||
|
].join("\n"), "git" )
|
||
|
break
|
||
|
|
||
|
case npm.ECYCLE:
|
||
|
er.code = "ECYCLE"
|
||
|
log.error([er.message
|
||
|
,"While installing: "+er.pkgid
|
||
|
,"Found a pathological dependency case that npm cannot solve."
|
||
|
,"Please report this to the package author."
|
||
|
].join("\n"))
|
||
|
break
|
||
|
|
||
|
case npm.ENOTSUP:
|
||
|
er.code = "ENOTSUP"
|
||
|
log.error([er.message
|
||
|
,"Not compatible with your version of node/npm: "+er.pkgid
|
||
|
,"Required: "+JSON.stringify(er.required)
|
||
|
,"Actual: "
|
||
|
+JSON.stringify({npm:npm.version
|
||
|
,node:npm.config.get("node-version")})
|
||
|
].join("\n"))
|
||
|
break
|
||
|
|
||
|
case "EEXIST":
|
||
|
case constants.EEXIST:
|
||
|
log.error([er.message
|
||
|
,"File exists: "+er.path
|
||
|
,"Move it away, and try again."].join("\n"))
|
||
|
break
|
||
|
|
||
|
default:
|
||
|
log.error(er)
|
||
|
log.error(["Report this *entire* log at:"
|
||
|
," <http://github.com/isaacs/npm/issues>"
|
||
|
,"or email it to:"
|
||
|
," <npm-@googlegroups.com>"
|
||
|
].join("\n"))
|
||
|
break
|
||
|
}
|
||
|
|
||
|
var os = require("os")
|
||
|
log.error("")
|
||
|
log.error(os.type() + " " + os.release(), "System")
|
||
|
log.error(process.argv
|
||
|
.map(JSON.stringify).join(" "), "command")
|
||
|
log.error(process.cwd(), "cwd")
|
||
|
log.error(process.version, "node -v")
|
||
|
log.error(npm.version, "npm -v")
|
||
|
|
||
|
; [ "file"
|
||
|
, "path"
|
||
|
, "type"
|
||
|
, "syscall"
|
||
|
, "fstream_path"
|
||
|
, "fstream_unc_path"
|
||
|
, "fstream_type"
|
||
|
, "fstream_class"
|
||
|
, "fstream_finish_call"
|
||
|
, "fstream_linkpath"
|
||
|
, "arguments"
|
||
|
, "code"
|
||
|
, "message"
|
||
|
].forEach(function (k) {
|
||
|
if (er[k]) log.error(er[k], k)
|
||
|
})
|
||
|
|
||
|
if (er.fstream_stack) {
|
||
|
log.error(er.fstream_stack.join("\n"), "fstream_stack")
|
||
|
}
|
||
|
|
||
|
if (er.errno && typeof er.errno !== "object") log.error(er.errno, "errno")
|
||
|
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()
|
||
|
writingLogFile = true
|
||
|
wroteLogFile = true
|
||
|
|
||
|
var fs = require("graceful-fs")
|
||
|
, fstr = fs.createWriteStream("npm-debug.log")
|
||
|
, util = require("util")
|
||
|
|
||
|
log.history.forEach(function (m) {
|
||
|
var lvl = log.LEVEL[m.level]
|
||
|
, pref = m.pref ? " " + m.pref : ""
|
||
|
, b = lvl + pref + " "
|
||
|
, eol = process.platform === "win32" ? "\r\n" : "\n"
|
||
|
, msg = typeof m.msg === "string" ? m.msg
|
||
|
: msg instanceof Error ? msg.stack || msg.message
|
||
|
: util.inspect(m.msg, 0, 4)
|
||
|
fstr.write(new Buffer(b
|
||
|
+(msg.split(/\r?\n+/).join(eol+b))
|
||
|
+ eol))
|
||
|
})
|
||
|
fstr.end()
|
||
|
fstr.on("close", cb)
|
||
|
}
|