PageRenderTime 60ms CodeModel.GetById 10ms app.highlight 45ms RepoModel.GetById 1ms app.codeStats 0ms

/nodejs/0.8.22/deps/npm/lib/utils/error-handler.js

https://bitbucket.org/mosaic/mosaic-distribution-dependencies
JavaScript | 305 lines | 257 code | 39 blank | 9 comment | 44 complexity | 708c5c85e838c2cfa4a63d21ad68b794 MD5 | raw file
  1
  2module.exports = errorHandler
  3
  4var cbCalled = false
  5  , log = require("npmlog")
  6  , npm = require("../npm.js")
  7  , rm = require("rimraf")
  8  , itWorked = false
  9  , path = require("path")
 10  , wroteLogFile = false
 11  , exitCode = 0
 12
 13
 14process.on("exit", function (code) {
 15  // console.error("exit", code)
 16  if (!npm.config.loaded) return
 17  if (code) itWorked = false
 18  if (itWorked) log.info("ok")
 19  else {
 20    if (!cbCalled) {
 21      log.error("", "cb() never called!")
 22    }
 23
 24    if (wroteLogFile) {
 25      log.error("", [""
 26                ,"Additional logging details can be found in:"
 27                ,"    " + path.resolve("npm-debug.log")
 28                ].join("\n"))
 29      wroteLogFile = false
 30    }
 31    log.error("not ok", "code", code)
 32  }
 33
 34  var doExit = npm.config.get("_exit")
 35  if (doExit) {
 36    // actually exit.
 37    if (exitCode === 0 && !itWorked) {
 38      exitCode = 1
 39    }
 40    if (exitCode !== 0) process.exit(exitCode)
 41  } else {
 42    itWorked = false // ready for next exit
 43  }
 44})
 45
 46function exit (code, noLog) {
 47  exitCode = exitCode || code
 48
 49  var doExit = npm.config.get("_exit")
 50  log.verbose("exit", [code, doExit])
 51  if (log.level === "silent") noLog = true
 52
 53  if (code && !noLog) writeLogFile(reallyExit)
 54  else rm("npm-debug.log", function () { rm(npm.tmp, reallyExit) })
 55
 56  function reallyExit() {
 57    // truncate once it's been written.
 58    log.record.length = 0
 59
 60    itWorked = !code
 61
 62    // just emit a fake exit event.
 63    // if we're really exiting, then let it exit on its own, so that
 64    // in-process stuff can finish or clean up first.
 65    if (!doExit) process.emit("exit", code)
 66  }
 67}
 68
 69
 70function errorHandler (er) {
 71  var printStack = false
 72  // console.error("errorHandler", er)
 73  if (!npm.config.loaded) {
 74    // logging won't work unless we pretend that it's ready
 75    er = er || new Error("Exit prior to config file resolving.")
 76    console.error(er.stack || er.message)
 77  }
 78
 79  if (cbCalled) {
 80    er = er || new Error("Callback called more than once.")
 81  }
 82
 83  cbCalled = true
 84  if (!er) return exit(0)
 85  if (typeof er === "string") {
 86    log.error("", er)
 87    return exit(1, true)
 88  } else if (!(er instanceof Error)) {
 89    log.error("weird error", er)
 90    return exit(1, true)
 91  }
 92
 93  var m = er.code || er.message.match(/^(?:Error: )?(E[A-Z]+)/)
 94  if (m && !er.code) er.code = m
 95
 96  switch (er.code) {
 97  case "ECONNREFUSED":
 98    log.error("", er)
 99    log.error("", ["\nIf you are behind a proxy, please make sure that the"
100              ,"'proxy' config is set properly.  See: 'npm help config'"
101              ].join("\n"))
102    printStack = true
103    break
104
105  case "EACCES":
106  case "EPERM":
107    log.error("", er)
108    log.error("", ["\nPlease try running this command again as root/Administrator."
109              ].join("\n"))
110    printStack = true
111    break
112
113  case "ELIFECYCLE":
114    er.code = "ELIFECYCLE"
115    log.error("", er.message)
116    log.error("", ["","Failed at the "+er.pkgid+" "+er.stage+" script."
117              ,"This is most likely a problem with the "+er.pkgname+" package,"
118              ,"not with npm itself."
119              ,"Tell the author that this fails on your system:"
120              ,"    "+er.script
121              ,"You can get their info via:"
122              ,"    npm owner ls "+er.pkgname
123              ,"There is likely additional logging output above."
124              ].join("\n"))
125    break
126
127  case "EJSONPARSE":
128    er.code = "EJSONPARSE"
129    log.error("", er.message)
130    log.error("", "File: "+er.file)
131    log.error("", ["Failed to parse package.json data."
132              ,"package.json must be actual JSON, not just JavaScript."
133              ,"","This is not a bug in npm."
134              ,"Tell the package author to fix their package.json file."
135              ].join("\n"), "JSON.parse")
136    break
137
138  case "E404":
139    er.code = "E404"
140    if (er.pkgid && er.pkgid !== "-") {
141      var msg = ["'"+er.pkgid+"' is not in the npm registry."
142                ,"You should bug the author to publish it"]
143      if (er.pkgid.match(/^node[\.\-]|[\.\-]js$/)) {
144        var s = er.pkgid.replace(/^node[\.\-]|[\.\-]js$/g, "")
145        if (s !== er.pkgid) {
146          s = s.replace(/[^a-z0-9]/g, ' ')
147          msg.push("\nMaybe try 'npm search " + s + "'")
148        }
149      }
150      msg.push("\nNote that you can also install from a"
151              ,"tarball, folder, or http url, or git url.")
152      log.error("404", msg.join("\n"))
153    }
154    break
155
156  case "EPUBLISHCONFLICT":
157    er.code = "EPUBLISHCONFLICT"
158    log.error("publish fail", ["Cannot publish over existing version."
159              ,"Update the 'version' field in package.json and try again."
160              ,""
161              ,"If the previous version was published in error, see:"
162              ,"    npm help unpublish"
163              ,""
164              ,"To automatically increment version numbers, see:"
165              ,"    npm help version"
166              ].join("\n"))
167    break
168
169  case "EISGIT":
170    er.code = "EISGIT"
171    log.error("git", [er.message
172              ,"    "+er.path
173              ,"Refusing to remove it. Update manually,"
174              ,"or move it out of the way first."
175              ].join("\n"))
176    break
177
178  case "ECYCLE":
179    er.code = "ECYCLE"
180    log.error("cycle", [er.message
181              ,"While installing: "+er.pkgid
182              ,"Found a pathological dependency case that npm cannot solve."
183              ,"Please report this to the package author."
184              ].join("\n"))
185    break
186
187  case "EBADPLATFORM":
188    er.code = "EBADPLATFORM"
189    log.error("notsup", [er.message
190              ,"Not compatible with your operating system or architecture: "+er.pkgid
191              ,"Valid OS:    "+er.os.join(",")
192              ,"Valid Arch:  "+er.cpu.join(",")
193              ,"Actual OS:   "+process.platform
194              ,"Actual Arch: "+process.arch
195              ].join("\n"))
196    break
197
198  case "EEXIST":
199    log.error([er.message
200              ,"File exists: "+er.path
201              ,"Move it away, and try again."].join("\n"))
202    break
203
204  case "ENEEDAUTH":
205    log.error("need auth", [er.message
206              ,"You need to authorize this machine using `npm adduser`"
207              ].join("\n"))
208    break
209
210  case "EPEERINVALID":
211    var peerErrors = Object.keys(er.peersDepending).map(function (peer) {
212      return "Peer " + peer + " wants " + er.packageName + "@"
213        + er.peersDepending[peer]
214    })
215    log.error("peerinvalid", [er.message].concat(peerErrors).join("\n"))
216    break
217
218  case "ENOTSUP":
219    if (er.required) {
220      log.error("notsup", [er.message
221                ,"Not compatible with your version of node/npm: "+er.pkgid
222                ,"Required: "+JSON.stringify(er.required)
223                ,"Actual:   "
224                +JSON.stringify({npm:npm.version
225                                ,node:npm.config.get("node-version")})
226                ].join("\n"))
227      break
228    } // else passthrough
229
230  default:
231    log.error("", er.stack || er.message || er)
232    log.error("", ["If you need help, you may report this log at:"
233                  ,"    <http://github.com/isaacs/npm/issues>"
234                  ,"or email it to:"
235                  ,"    <npm-@googlegroups.com>"
236                  ].join("\n"))
237    printStack = false
238    break
239  }
240
241  var os = require("os")
242  // just a line break
243  console.error("")
244  log.error("System", os.type() + " " + os.release())
245  log.error("command", process.argv
246            .map(JSON.stringify).join(" "))
247  log.error("cwd", process.cwd())
248  log.error("node -v", process.version)
249  log.error("npm -v", npm.version)
250
251  ; [ "file"
252    , "path"
253    , "type"
254    , "syscall"
255    , "fstream_path"
256    , "fstream_unc_path"
257    , "fstream_type"
258    , "fstream_class"
259    , "fstream_finish_call"
260    , "fstream_linkpath"
261    , "code"
262    , "errno"
263    , "stack"
264    , "fstream_stack"
265    ].forEach(function (k) {
266      var v = er[k]
267      if (k === "stack") {
268        if (!printStack) return
269        if (!v) v = er.message
270      }
271      if (!v) return
272      if (k === "fstream_stack") v = v.join("\n")
273      log.error(k, v)
274    })
275
276  exit(typeof er.errno === "number" ? er.errno : 1)
277}
278
279var writingLogFile = false
280function writeLogFile (cb) {
281  if (writingLogFile) return cb()
282  writingLogFile = true
283  wroteLogFile = true
284
285  var fs = require("graceful-fs")
286    , fstr = fs.createWriteStream("npm-debug.log")
287    , util = require("util")
288    , eol = process.platform === "win32" ? "\r\n" : "\n"
289    , out = ""
290
291  log.record.forEach(function (m) {
292    var pref = [m.id, m.level]
293    if (m.prefix) pref.push(m.prefix)
294    pref = pref.join(' ')
295
296    m.message.trim().split(/\r?\n/).map(function (line) {
297      return (pref + ' ' + line).trim()
298    }).forEach(function (line) {
299      out += line + eol
300    })
301  })
302
303  fstr.end(out)
304  fstr.on("close", cb)
305}