PageRenderTime 50ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/utils/error-handler.js

https://github.com/cspotcode/npm
JavaScript | 241 lines | 210 code | 26 blank | 5 comment | 35 complexity | cfe4bcf7762c9b6b26c6d8c59115a89a MD5 | raw file
Possible License(s): LGPL-2.0
  1. module.exports = errorHandler
  2. var cbCalled = false
  3. , log = require("./log.js")
  4. , npm = require("../../npm.js")
  5. , rm = require("rimraf")
  6. , constants = require("constants")
  7. , itWorked = false
  8. , path = require("path")
  9. , ini = require("./ini.js")
  10. process.on("exit", function (code) {
  11. // console.error("exit", code)
  12. if (!ini.resolved) return
  13. if (code) itWorked = false
  14. if (itWorked) log("ok")
  15. else {
  16. if (!cbCalled) {
  17. log.error("cb() never called!\n ")
  18. }
  19. log.error([""
  20. ,"Additional logging details can be found in:"
  21. ," " + path.resolve("npm-debug.log")
  22. ].join("\n"))
  23. log.win("not ok")
  24. }
  25. itWorked = false // ready for next exit
  26. })
  27. function errorHandler (er) {
  28. // console.error("errorHandler", er)
  29. if (!ini.resolved) {
  30. // logging won't work unless we pretend that it's ready
  31. er = er || new Error("Exit prior to config file resolving.")
  32. console.error(er.stack || er.message)
  33. }
  34. if (cbCalled) {
  35. er = er || new Error("Callback called more than once.")
  36. }
  37. cbCalled = true
  38. if (!er) return exit(0)
  39. if (!(er instanceof Error)) {
  40. log.error(er)
  41. return exit(1)
  42. }
  43. var m = er.code || er.message.match(/^(?:Error: )?(E[A-Z]+)/)
  44. if (m) {
  45. m = m[1]
  46. if (!constants[m] && !npm[m]) constants[m] = {}
  47. er.errno = npm[m] || constants[m]
  48. }
  49. switch (er.errno) {
  50. case "ECONNREFUSED":
  51. case constants.ECONNREFUSED:
  52. log.error(er)
  53. log.error(["If you are using Cygwin, please set up your /etc/resolv.conf"
  54. ,"See step 4 in this wiki page:"
  55. ," http://github.com/ry/node/wiki/Building-node.js-on-Cygwin-%28Windows%29"
  56. ,"If you are not using Cygwin, please report this"
  57. ,"at <http://github.com/isaacs/npm/issues>"
  58. ,"or email it to <npm-@googlegroups.com>"
  59. ].join("\n"))
  60. break
  61. case "EACCES":
  62. case "EPERM":
  63. case constants.EACCES:
  64. case constants.EPERM:
  65. log.error(er)
  66. log.error(["",
  67. "Please use 'sudo' or log in as root to run this command."
  68. ,""
  69. ," sudo npm "
  70. +npm.config.get("argv").original.map(JSON.stringify).join(" ")
  71. ,""
  72. ,"or set the 'unsafe-perm' config var to true."
  73. ,""
  74. ," npm config set unsafe-perm true"
  75. ].join("\n"))
  76. break
  77. case npm.ELIFECYCLE:
  78. er.code = "ELIFECYCLE"
  79. log.error(er.message)
  80. log.error(["","Failed at the "+er.pkgid+" "+er.stage+" script."
  81. ,"This is most likely a problem with the "+er.pkgname+" package,"
  82. ,"not with npm itself."
  83. ,"Tell the author that this fails on your system:"
  84. ," "+er.script
  85. ,"You can get their info via:"
  86. ," npm owner ls "+er.pkgname
  87. ,"There is likely additional logging output above."
  88. ].join("\n"))
  89. break
  90. case npm.EJSONPARSE:
  91. er.code = "EJSONPARSE"
  92. log.error(er.message)
  93. log.error("File: "+er.file)
  94. log.error(["Failed to parse package.json data."
  95. ,"package.json must be actual JSON, not just JavaScript."
  96. ,"","This is not a bug in npm."
  97. ,"Tell the package author to fix their package.json file."
  98. ].join("\n"), "JSON.parse")
  99. break
  100. case npm.E404:
  101. er.code = "E404"
  102. if (er.pkgid && er.pkgid !== "-") {
  103. var msg = ["'"+er.pkgid+"' is not in the npm registry."
  104. ,"You could maybe bug the author to publish it"]
  105. if (er.pkgid.match(/^node[\.\-]|[\.\-]js$/)) {
  106. var s = er.pkgid.replace(/^node[\.\-]|[\.\-]js$/g, "")
  107. if (s !== er.pkgid) {
  108. s = s.replace(/[^a-z0-9]/g, ' ')
  109. msg.push("Maybe try 'npm search " + s + "'")
  110. }
  111. }
  112. msg.push("Note that you can also install from a tarball or folder.")
  113. log.error(msg.join("\n"), "404")
  114. }
  115. break
  116. case npm.EPUBLISHCONFLICT:
  117. er.code = "EPUBLISHCONFLICT"
  118. log.error(["Cannot publish over existing version."
  119. ,"Bump the 'version' field, set the --force flag, or"
  120. ," npm unpublish '"+er.pkgid+"'"
  121. ,"and try again"
  122. ].join("\n"), "publish fail" )
  123. break
  124. case npm.EISGIT:
  125. er.code = "EISGIT"
  126. log.error([er.message
  127. ," "+er.path
  128. ,"Refusing to remove it. Update manually,"
  129. ,"or move it out of the way first."
  130. ].join("\n"), "git" )
  131. break
  132. case npm.ECYCLE:
  133. er.code = "ECYCLE"
  134. log.error([er.message
  135. ,"While installing: "+er.pkgid
  136. ,"Found a pathological dependency case that npm cannot solve."
  137. ,"Please report this to the package author."
  138. ].join("\n"))
  139. break
  140. case npm.ENOTSUP:
  141. er.code = "ENOTSUP"
  142. log.error([er.message
  143. ,"Not compatible with your version of node/npm: "+er.pkgid
  144. ,"Required: "+JSON.stringify(er.required)
  145. ,"Actual: "
  146. +JSON.stringify({npm:npm.version
  147. ,node:npm.config.get("node-version")})
  148. ].join("\n"))
  149. break
  150. case "EEXIST":
  151. case constants.EEXIST:
  152. log.error([er.message
  153. ,"File exists: "+er.path
  154. ,"Move it away, and try again."].join("\n"))
  155. break
  156. default:
  157. log.error(er)
  158. log.error(["Report this *entire* log at:"
  159. ," <http://github.com/isaacs/npm/issues>"
  160. ,"or email it to:"
  161. ," <npm-@googlegroups.com>"
  162. ].join("\n"))
  163. break
  164. }
  165. var os = require("os")
  166. log.error("")
  167. log.error(os.type() + " " + os.release(), "System")
  168. log.error(process.argv
  169. .map(JSON.stringify).join(" "), "command")
  170. log.error(process.cwd(), "cwd")
  171. log.error(process.version, "node -v")
  172. log.error(npm.version, "npm -v")
  173. if (er.file) log.error(er.file, "file")
  174. if (er.path) log.error(er.path, "path")
  175. if (er.type) log.error(er.type, "type")
  176. if (er.arguments) log.error(er.arguments, "arguments")
  177. if (er.code) log.error(er.code, "code")
  178. if (er.errno && typeof er.errno !== "object") log.error(er.errno, "errno")
  179. exit(typeof er.errno === "number" ? er.errno : 1)
  180. }
  181. function exit (code) {
  182. var doExit = npm.config.get("_exit")
  183. log.verbose([code, doExit], "exit")
  184. if (code) writeLogFile(reallyExit)
  185. else rm("npm-debug.log", function () { rm(npm.tmp, reallyExit) })
  186. function reallyExit() {
  187. itWorked = !code
  188. //if (!itWorked) {
  189. if (!doExit) process.emit("exit", code)
  190. else process.exit(code)
  191. //}
  192. }
  193. }
  194. var writingLogFile = false
  195. function writeLogFile (cb) {
  196. if (writingLogFile) return cb()
  197. writingLogFile = true
  198. var fs = require("graceful-fs")
  199. , fstr = fs.createWriteStream("npm-debug.log")
  200. , util = require("util")
  201. log.history.forEach(function (m) {
  202. var lvl = log.LEVEL[m.level]
  203. , pref = m.pref ? " " + m.pref : ""
  204. , b = lvl + pref + " "
  205. , eol = process.platform === "win32" ? "\r\n" : "\n"
  206. , msg = typeof m.msg === "string" ? m.msg
  207. : msg instanceof Error ? msg.stack || msg.message
  208. : util.inspect(m.msg, 0, 4)
  209. fstr.write(new Buffer(b
  210. +(msg.split(/\r?\n+/).join(eol+b))
  211. + eol))
  212. })
  213. fstr.end()
  214. fstr.on("close", cb)
  215. }