1
0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-02-21 07:29:37 +01:00

use http-errors package instead of custom stuff

This commit is contained in:
Alex Kocharin 2014-09-10 21:55:26 +04:00
parent dbb588f031
commit a5cd498f92
11 changed files with 79 additions and 252 deletions

@ -1,6 +1,6 @@
var Path = require('path') var Path = require('path')
, crypto = require('crypto') , crypto = require('crypto')
, UError = require('./error').UserError , Error = require('http-errors')
, Logger = require('./logger') , Logger = require('./logger')
, assert = require('assert') , assert = require('assert')
@ -65,10 +65,8 @@ function Auth(config) {
}, },
adduser: function(user, password, cb) { adduser: function(user, password, cb) {
if (config.users && config.users[user]) return cb(new UError({ if (config.users && config.users[user])
status: 403, return cb(Error[403]('this user already exists'))
message: 'this user already exists',
}))
return cb() return cb()
}, },
@ -76,17 +74,11 @@ function Auth(config) {
this.plugins.push({ this.plugins.push({
authenticate: function(user, password, cb) { authenticate: function(user, password, cb) {
return cb(new UError({ return cb(Error[403]('bad username/password, access denied'))
status: 403,
message: 'bad username/password, access denied',
}))
}, },
adduser: function(user, password, cb) { adduser: function(user, password, cb) {
return cb(new UError({ return cb(Error[409]('registration is disabled'))
status: 409,
message: 'registration is disabled',
}))
}, },
}) })
} }

@ -2,7 +2,7 @@ var assert = require('assert')
, crypto = require('crypto') , crypto = require('crypto')
, Path = require('path') , Path = require('path')
, minimatch = require('minimatch') , minimatch = require('minimatch')
, UError = require('./error').UserError , Error = require('http-errors')
, LocalList = require('./local-list') , LocalList = require('./local-list')
, utils = require('./utils') , utils = require('./utils')

@ -1,62 +0,0 @@
var util = require('util')
, utils = require('./utils')
function parse_error_params(params, status, message) {
if (typeof(params) === 'string') {
return {
message: params,
status: status,
}
} else if (typeof(params) === 'number') {
return {
message: message,
status: params,
}
} else if (utils.is_object(params)) {
if (params.message == null) params.message = message
if (params.status == null) params.status = status
return params
} else {
return {
message: message,
status: status,
}
}
}
/*
* Errors caused by malfunctioned code
*/
var AppError = function(params, constr) {
Error.captureStackTrace(this, constr || this)
params = parse_error_params(params, 500, 'Internal server error')
this.message = params.message
this.status = params.status
}
util.inherits(AppError, Error)
AppError.prototype.name = 'Application Error'
/*
* Errors caused by wrong request
*/
var UserError = function(params, constr) {
params = parse_error_params(params, 404, 'The requested resource was not found')
this.message = params.message
this.status = params.status
}
util.inherits(UserError, Error)
UserError.prototype.name = 'User Error'
/*
* Mimic filesystem errors
*/
var FSError = function(code) {
this.code = code
}
util.inherits(UserError, Error)
UserError.prototype.name = 'FS Error'
module.exports.AppError = AppError
module.exports.UserError = UserError
module.exports.FSError = FSError

@ -3,7 +3,7 @@ var express = require('express')
, utils = require('./utils') , utils = require('./utils')
, Storage = require('./storage') , Storage = require('./storage')
, Config = require('./config') , Config = require('./config')
, UError = require('./error').UserError , Error = require('http-errors')
, Middleware = require('./middleware') , Middleware = require('./middleware')
, Logger = require('./logger') , Logger = require('./logger')
, Cats = require('./status-cats') , Cats = require('./status-cats')
@ -39,15 +39,10 @@ module.exports = function(config_hash) {
} else { } else {
var message = "can't "+action+" restricted package without auth, did you forget 'npm set always-auth true'?" var message = "can't "+action+" restricted package without auth, did you forget 'npm set always-auth true'?"
} }
next(new UError({ next(Error[403](message))
status: 403,
message: message,
}))
} else { } else {
next(new UError({ next(Error[403]('user ' + req.remote_user.name
status: 403, + ' not allowed to ' + action + ' it'))
message: 'user '+req.remote_user.name+' not allowed to '+action+' it'
}))
} }
} }
} }
@ -144,10 +139,7 @@ module.exports = function(config_hash) {
} }
} }
return next(new UError({ return next(Error[404]('version not found: ' + req.params.version))
status: 404,
message: 'version not found: ' + req.params.version
}))
}) })
}) })
@ -205,20 +197,14 @@ module.exports = function(config_hash) {
}) })
} else { } else {
if (typeof(req.body.name) !== 'string' || typeof(req.body.password) !== 'string') { if (typeof(req.body.name) !== 'string' || typeof(req.body.password) !== 'string') {
return next(new UError({ return next(Error[400]('user/password is not found in request (npm issue?)'))
status: 400,
message: 'user/password is not found in request (npm issue?)',
}))
} }
auth.add_user(req.body.name, req.body.password, function(err) { auth.add_user(req.body.name, req.body.password, function(err) {
if (err) { if (err) {
if (err.status < 500 && err.message === 'this user already exists') { if (err.status < 500 && err.message === 'this user already exists') {
// with npm registering is the same as logging in // with npm registering is the same as logging in
// so we replace message in case of conflict // so we replace message in case of conflict
return next(new UError({ return next(Error[409]('bad username/password, access denied'))
status: 409,
message: 'bad username/password, access denied'
}))
} }
return next(err) return next(err)
} }
@ -251,20 +237,14 @@ module.exports = function(config_hash) {
var name = req.params.package var name = req.params.package
if (Object.keys(req.body).length == 1 && utils.is_object(req.body.users)) { if (Object.keys(req.body).length == 1 && utils.is_object(req.body.users)) {
return next(new UError({ // 501 status is more meaningful, but npm doesn't show error message for 5xx
// 501 status is more meaningful, but npm doesn't show error message for 5xx return next(Error[404]('npm star|unstar calls are not implemented'))
status: 404,
message: 'npm star|unstar calls are not implemented',
}))
} }
try { try {
var metadata = utils.validate_metadata(req.body, name) var metadata = utils.validate_metadata(req.body, name)
} catch(err) { } catch(err) {
return next(new UError({ return next(Error[422]('bad incoming package data'))
status: 422,
message: 'bad incoming package data',
}))
} }
if (req.params._rev) { if (req.params._rev) {
@ -298,10 +278,7 @@ module.exports = function(config_hash) {
// npm is doing something strange again // npm is doing something strange again
// if this happens in normal circumstances, report it as a bug // if this happens in normal circumstances, report it as a bug
return next(new UError({ return next(Error[400]('unsupported registry call'))
status: 400,
message: 'unsupported registry call',
}))
} }
if (err && err.status != 409) return next(err) if (err && err.status != 409) return next(err)

@ -2,7 +2,13 @@ var fs = require('fs')
, Path = require('path') , Path = require('path')
, mkdirp = require('mkdirp') , mkdirp = require('mkdirp')
, mystreams = require('./streams') , mystreams = require('./streams')
, FSError = require('./error').FSError , Error = require('http-errors')
function FSError(code) {
var err = Error(code)
err.code = code
return err
}
try { try {
var fsExt = require('fs-ext') var fsExt = require('fs-ext')
@ -44,7 +50,7 @@ function write_stream(name) {
}) })
fs.exists(name, function(exists) { fs.exists(name, function(exists) {
if (exists) return stream.emit('error', new FSError('EEXISTS')) if (exists) return stream.emit('error', FSError('EEXISTS'))
var tmpname = name + '.tmp-'+String(Math.random()).replace(/^0\./, '') var tmpname = name + '.tmp-'+String(Math.random()).replace(/^0\./, '')
, file = fs.createWriteStream(tmpname) , file = fs.createWriteStream(tmpname)
@ -114,14 +120,14 @@ function read_stream(name, stream, callback) {
function create(name, contents, callback) { function create(name, contents, callback) {
fs.exists(name, function(exists) { fs.exists(name, function(exists) {
if (exists) return callback(new FSError('EEXISTS')) if (exists) return callback(FSError('EEXISTS'))
write(name, contents, callback) write(name, contents, callback)
}) })
} }
function update(name, contents, callback) { function update(name, contents, callback) {
fs.exists(name, function(exists) { fs.exists(name, function(exists) {
if (!exists) return callback(new FSError('ENOENT')) if (!exists) return callback(FSError('ENOENT'))
write(name, contents, callback) write(name, contents, callback)
}) })
} }
@ -167,7 +173,7 @@ function lock_and_read(name, callback) {
var buffer = new Buffer(st.size) var buffer = new Buffer(st.size)
fs.read(fd, buffer, 0, st.size, null, function(err, bytesRead, buffer) { fs.read(fd, buffer, 0, st.size, null, function(err, bytesRead, buffer) {
if (err) return callback(err) if (err) return callback(err)
if (bytesRead != st.size) return callback(new Error('st.size != bytesRead'), fd) if (bytesRead != st.size) return callback(Error('st.size != bytesRead'), fd)
callback(null, fd, buffer) callback(null, fd, buffer)
}) })

@ -3,7 +3,7 @@ var fs = require('fs')
, crypto = require('crypto') , crypto = require('crypto')
, assert = require('assert') , assert = require('assert')
, fs_storage = require('./local-fs') , fs_storage = require('./local-fs')
, UError = require('./error').UserError , Error = require('http-errors')
, utils = require('./utils') , utils = require('./utils')
, mystreams = require('./streams') , mystreams = require('./streams')
, Logger = require('./logger') , Logger = require('./logger')
@ -41,26 +41,17 @@ Storage.prototype._internal_error = function(err, file, message) {
this.logger.error( {err: err, file: file} this.logger.error( {err: err, file: file}
, message + ' @{file}: @{!err.message}' , message + ' @{file}: @{!err.message}'
) )
return new UError({ return Error[500]()
status: 500,
message: 'internal server error'
})
} }
Storage.prototype.add_package = function(name, info, callback) { Storage.prototype.add_package = function(name, info, callback) {
var self = this var self = this
var storage = this.storage(name) var storage = this.storage(name)
if (!storage) return callback(new UError({ if (!storage) return callback(Error[404]('this package cannot be added'))
status: 404,
message: 'this package cannot be added'
}))
storage.create_json(info_file, get_boilerplate(name), function(err) { storage.create_json(info_file, get_boilerplate(name), function(err) {
if (err && err.code === 'EEXISTS') { if (err && err.code === 'EEXISTS') {
return callback(new UError({ return callback(Error[409]('this package is already present'))
status: 409,
message: 'this package is already present'
}))
} }
var latest = info['dist-tags'].latest var latest = info['dist-tags'].latest
@ -76,17 +67,12 @@ Storage.prototype.remove_package = function(name, callback) {
self.logger.info({name: name}, 'unpublishing @{name} (all)') self.logger.info({name: name}, 'unpublishing @{name} (all)')
var storage = self.storage(name) var storage = self.storage(name)
if (!storage) return callback(new UError({ if (!storage) return callback(Error[404]('no such package available'))
status: 404,
message: 'no such package available',
}))
storage.read_json(info_file, function(err, data) { storage.read_json(info_file, function(err, data) {
if (err) { if (err) {
if (err.code === 'ENOENT') { if (err.code === 'ENOENT') {
return callback(new UError({ return callback(Error[404]('no such package available'))
status: 404,
message: 'no such package available',
}))
} else { } else {
return callback(err) return callback(err)
} }
@ -222,10 +208,7 @@ Storage.prototype.add_version = function(name, version, metadata, tag, callback)
delete metadata.readme delete metadata.readme
if (data.versions[version] != null) { if (data.versions[version] != null) {
return cb(new UError({ return cb(Error[409]('this version already present'))
status: 409,
message: 'this version already present'
}))
} }
// if uploaded tarball has a different shasum, it's very likely that we have some kind of error // if uploaded tarball has a different shasum, it's very likely that we have some kind of error
@ -234,10 +217,9 @@ Storage.prototype.add_version = function(name, version, metadata, tag, callback)
if (utils.is_object(data._attachments[tarball])) { if (utils.is_object(data._attachments[tarball])) {
if (data._attachments[tarball].shasum != null && metadata.dist.shasum != null) { if (data._attachments[tarball].shasum != null && metadata.dist.shasum != null) {
if (data._attachments[tarball].shasum != metadata.dist.shasum) { if (data._attachments[tarball].shasum != metadata.dist.shasum) {
return cb(new UError({ return cb(Error[400]('shasum error, '
status: 400, + data._attachments[tarball].shasum
message: 'shasum error, ' + data._attachments[tarball].shasum + ' != ' + metadata.dist.shasum, + ' != ' + metadata.dist.shasum))
}))
} }
} }
@ -258,10 +240,7 @@ Storage.prototype.add_tags = function(name, tags, callback) {
self.update_package(name, function updater(data, cb) { self.update_package(name, function updater(data, cb) {
for (var t in tags) { for (var t in tags) {
if (data.versions[tags[t]] == null) { if (data.versions[tags[t]] == null) {
return cb(new UError({ return cb(Error[404]("this version doesn't exist"))
status: 404,
message: "this version doesn't exist"
}))
} }
utils.tag_version(data, tags[t], t, self.config) utils.tag_version(data, tags[t], t, self.config)
@ -280,10 +259,7 @@ Storage.prototype.change_package = function(name, metadata, revision, callback)
var self = this var self = this
if (!utils.is_object(metadata.versions) || !utils.is_object(metadata['dist-tags'])) { if (!utils.is_object(metadata.versions) || !utils.is_object(metadata['dist-tags'])) {
return callback(new UError({ return callback(Error[422]('bad data'))
status: 422,
message: 'bad data',
}))
} }
self.update_package(name, function updater(data, cb) { self.update_package(name, function updater(data, cb) {
@ -316,10 +292,7 @@ Storage.prototype.remove_tarball = function(name, filename, revision, callback)
delete data._attachments[filename] delete data._attachments[filename]
cb() cb()
} else { } else {
cb(new UError({ cb(Error[404]('no such file available'))
status: 404,
message: 'no such file available',
}))
} }
}, function(err) { }, function(err) {
if (err) return callback(err) if (err) return callback(err)
@ -347,10 +320,7 @@ Storage.prototype.add_tarball = function(name, filename) {
var self = this var self = this
if (name === info_file || name === '__proto__') { if (name === info_file || name === '__proto__') {
process.nextTick(function() { process.nextTick(function() {
stream.emit('error', new UError({ stream.emit('error', Error[403]("can't use this filename"))
status: 403,
message: 'can\'t use this filename'
}))
}) })
return stream return stream
} }
@ -358,10 +328,7 @@ Storage.prototype.add_tarball = function(name, filename) {
var storage = self.storage(name) var storage = self.storage(name)
if (!storage) { if (!storage) {
process.nextTick(function() { process.nextTick(function() {
stream.emit('error', new UError({ stream.emit('error', Error[404]("can't upload this package"))
status: 404,
message: 'can\'t upload this package'
}))
}) })
return stream return stream
} }
@ -370,10 +337,7 @@ Storage.prototype.add_tarball = function(name, filename) {
wstream.on('error', function(err) { wstream.on('error', function(err) {
if (err.code === 'EEXISTS') { if (err.code === 'EEXISTS') {
stream.emit('error', new UError({ stream.emit('error', Error[409]('this tarball is already present'))
status: 409,
message: 'this tarball is already present'
}))
} else if (err.code === 'ENOENT') { } else if (err.code === 'ENOENT') {
// check if package exists to throw an appropriate message // check if package exists to throw an appropriate message
self.get_package(name, function(_err, res) { self.get_package(name, function(_err, res) {
@ -411,10 +375,7 @@ Storage.prototype.add_tarball = function(name, filename) {
} }
stream.done = function() { stream.done = function() {
if (!length) { if (!length) {
stream.emit('error', new UError({ stream.emit('error', Error[422]('refusing to accept zero-length file'))
status: 422,
message: 'refusing to accept zero-length file'
}))
wstream.abort() wstream.abort()
} else { } else {
wstream.done() wstream.done()
@ -440,7 +401,6 @@ Storage.prototype.get_readme = function(name, version, callback) {
if (exists) { if (exists) {
returnReadme(); returnReadme();
} else { } else {
debugger
self.unpack_tarball(fileName, function(err) { self.unpack_tarball(fileName, function(err) {
returnReadme(); returnReadme();
}); });
@ -455,7 +415,7 @@ debugger
callback(data) callback(data)
}) })
} }
}; }
Storage.prototype.get_tarball = function(name, filename, callback) { Storage.prototype.get_tarball = function(name, filename, callback) {
assert(utils.validate_name(filename)) assert(utils.validate_name(filename))
@ -469,10 +429,7 @@ Storage.prototype.get_tarball = function(name, filename, callback) {
var storage = self.storage(name) var storage = self.storage(name)
if (!storage) { if (!storage) {
process.nextTick(function() { process.nextTick(function() {
stream.emit('error', new UError({ stream.emit('error', Error[404]('no such file available'))
status: 404,
message: 'no such file available',
}))
}) })
return stream return stream
} }
@ -480,10 +437,7 @@ Storage.prototype.get_tarball = function(name, filename, callback) {
var rstream = storage.read_stream(filename) var rstream = storage.read_stream(filename)
rstream.on('error', function(err) { rstream.on('error', function(err) {
if (err && err.code === 'ENOENT') { if (err && err.code === 'ENOENT') {
stream.emit('error', new UError({ stream.emit('error', Error(404, 'no such file available'))
status: 404,
message: 'no such file available',
}))
} else { } else {
stream.emit('error', err) stream.emit('error', err)
} }
@ -504,18 +458,12 @@ Storage.prototype.get_package = function(name, options, callback) {
var self = this var self = this
var storage = self.storage(name) var storage = self.storage(name)
if (!storage) return callback(new UError({ if (!storage) return callback(Error[404]('no such package available'))
status: 404,
message: 'no such package available'
}))
storage.read_json(info_file, function(err, result) { storage.read_json(info_file, function(err, result) {
if (err) { if (err) {
if (err.code === 'ENOENT') { if (err.code === 'ENOENT') {
return callback(new UError({ return callback(Error[404]('no such package available'))
status: 404,
message: 'no such package available'
}))
} else { } else {
return callback(self._internal_error(err, info_file, 'error reading')) return callback(self._internal_error(err, info_file, 'error reading'))
} }
@ -575,10 +523,7 @@ Storage.prototype.get_recent_packages = function(startkey, callback) {
Storage.prototype.update_package = function(name, updateFn, _callback) { Storage.prototype.update_package = function(name, updateFn, _callback) {
var self = this var self = this
var storage = self.storage(name) var storage = self.storage(name)
if (!storage) return _callback(new UError({ if (!storage) return _callback(Error[404]('no such package available'))
status: 404,
message: 'no such package available',
}))
storage.lock_and_read_json(info_file, function(err, fd, json) { storage.lock_and_read_json(info_file, function(err, fd, json) {
function callback() { function callback() {
var _args = arguments var _args = arguments
@ -594,15 +539,9 @@ Storage.prototype.update_package = function(name, updateFn, _callback) {
if (err) { if (err) {
if (err.code === 'EAGAIN') { if (err.code === 'EAGAIN') {
return callback(new UError({ return callback(Error[503]('resource temporarily unavailable'))
status: 503,
message: 'resource temporarily unavailable'
}))
} else if (err.code === 'ENOENT') { } else if (err.code === 'ENOENT') {
return callback(new UError({ return callback(Error[404]('no such package available'))
status: 404,
message: 'no such package available',
}))
} else { } else {
return callback(err) return callback(err)
} }

@ -1,4 +1,5 @@
var Logger = require('bunyan') var Logger = require('bunyan')
, Error = require('http-errors')
, Stream = require('stream') , Stream = require('stream')
, utils = require('./utils') , utils = require('./utils')
@ -49,7 +50,7 @@ module.exports.setup = function(logs) {
} }
} }
} else { } else {
throw new Error('wrong target type for a log') throw Error('wrong target type for a log')
} }
if (target.level === 'http') target.level = 35 if (target.level === 'http') target.level = 35

@ -1,6 +1,6 @@
var crypto = require('crypto') var crypto = require('crypto')
, Error = require('http-errors')
, utils = require('./utils') , utils = require('./utils')
, UError = require('./error').UserError
, Logger = require('./logger') , Logger = require('./logger')
module.exports.validate_name = function validate_name(req, res, next, value, name) { module.exports.validate_name = function validate_name(req, res, next, value, name) {
@ -10,20 +10,15 @@ module.exports.validate_name = function validate_name(req, res, next, value, nam
} else if (utils.validate_name(value)) { } else if (utils.validate_name(value)) {
next() next()
} else { } else {
next(new UError({ next(Error[403]('invalid ' + name))
status: 403,
message: 'invalid ' + name,
}))
} }
} }
module.exports.media = function media(expect) { module.exports.media = function media(expect) {
return function(req, res, next) { return function(req, res, next) {
if (req.headers['content-type'] !== expect) { if (req.headers['content-type'] !== expect) {
next(new UError({ next(Error[415]('wrong content-type, expect: ' + expect
status: 415, + ', got: '+req.headers['content-type']))
message: 'wrong content-type, expect: '+expect+', got: '+req.headers['content-type'],
}))
} else { } else {
next() next()
} }
@ -47,10 +42,7 @@ module.exports.anti_loop = function(config) {
for (var i=0; i<arr.length; i++) { for (var i=0; i<arr.length; i++) {
var m = arr[i].match(/\s*(\S+)\s+(\S+)/) var m = arr[i].match(/\s*(\S+)\s+(\S+)/)
if (m && m[2] === config.server_id) { if (m && m[2] === config.server_id) {
return next(new UError({ return next(Error[508]('loop detected'))
status: 508,
message: 'loop detected',
}))
} }
} }
} }

@ -1,6 +1,6 @@
var async = require('async') var async = require('async')
, assert = require('assert') , assert = require('assert')
, UError = require('./error').UserError , Error = require('http-errors')
, Local = require('./local-storage') , Local = require('./local-storage')
, Proxy = require('./up-storage') , Proxy = require('./up-storage')
, mystreams = require('./streams') , mystreams = require('./streams')
@ -63,10 +63,7 @@ Storage.prototype.add_package = function(name, metadata, callback) {
if (err && err.status !== 404) return cb(err) if (err && err.status !== 404) return cb(err)
if (results) { if (results) {
return cb(new UError({ return cb(Error[409]('this package is already present'))
status: 409,
message: 'this package is already present'
}))
} }
cb() cb()
@ -80,10 +77,7 @@ Storage.prototype.add_package = function(name, metadata, callback) {
// checking package // checking package
if (results) { if (results) {
return cb(new UError({ return cb(Error[409]('this package is already present'))
status: 409,
message: 'this package is already present'
}))
} }
for (var i=0; i<err_results.length; i++) { for (var i=0; i<err_results.length; i++) {
@ -91,10 +85,7 @@ Storage.prototype.add_package = function(name, metadata, callback) {
// if uplink fails with a status other than 404, we report failure // if uplink fails with a status other than 404, we report failure
if (err_results[i][0] != null) { if (err_results[i][0] != null) {
if (err_results[i][0].status !== 404) { if (err_results[i][0].status !== 404) {
return cb(new UError({ return cb(Error[503]('one of the uplinks is down, refuse to publish'))
status: 503,
message: 'one of the uplinks is down, refuse to publish'
}))
} }
} }
} }
@ -491,7 +482,7 @@ Storage.prototype._sync_package_with_uplinks = function(name, pkginfo, options,
if (err && err.status === 304) if (err && err.status === 304)
pkginfo._uplinks[up.upname].fetched = Date.now() pkginfo._uplinks[up.upname].fetched = Date.now()
if (err || !up_res) return cb(null, [err || new Error('no data')]) if (err || !up_res) return cb(null, [err || Error('no data')])
try { try {
utils.validate_metadata(up_res, name) utils.validate_metadata(up_res, name)
@ -527,10 +518,9 @@ Storage.prototype._sync_package_with_uplinks = function(name, pkginfo, options,
assert(!err && Array.isArray(uplink_errors)) assert(!err && Array.isArray(uplink_errors))
if (!exists) { if (!exists) {
return callback(new UError({ return callback( Error[404]('no such package available')
status: 404, , null
message: 'no such package available' , uplink_errors )
}), null, uplink_errors)
} }
self.local.update_versions(name, pkginfo, function(err, pkginfo) { self.local.update_versions(name, pkginfo, function(err, pkginfo) {

@ -2,7 +2,7 @@ var URL = require('url')
, request = require('request') , request = require('request')
, Stream = require('stream') , Stream = require('stream')
, zlib = require('zlib') , zlib = require('zlib')
, UError = require('./error').UserError , Error = require('http-errors')
, mystreams = require('./streams') , mystreams = require('./streams')
, Logger = require('./logger') , Logger = require('./logger')
, utils = require('./utils') , utils = require('./utils')
@ -101,8 +101,8 @@ Storage.prototype.request = function(options, cb) {
if (!this.status_check()) { if (!this.status_check()) {
var req = new Stream.Readable() var req = new Stream.Readable()
process.nextTick(function() { process.nextTick(function() {
if (typeof(cb) === 'function') cb(new Error('uplink is offline')) if (typeof(cb) === 'function') cb(Error('uplink is offline'))
req.emit('error', new Error('uplink is offline')) req.emit('error', Error('uplink is offline'))
}) })
// preventing 'Uncaught, unspecified "error" event' // preventing 'Uncaught, unspecified "error" event'
req.on('error', function(){}) req.on('error', function(){})
@ -265,14 +265,11 @@ Storage.prototype.get_package = function(name, options, callback) {
}, function(err, res, body) { }, function(err, res, body) {
if (err) return callback(err) if (err) return callback(err)
if (res.statusCode === 404) { if (res.statusCode === 404) {
return callback(new UError({ return callback(Error[404]("package doesn't exist on uplink"))
message: 'package doesn\'t exist on uplink',
status: 404,
}))
} }
if (!(res.statusCode >= 200 && res.statusCode < 300)) { if (!(res.statusCode >= 200 && res.statusCode < 300)) {
var error = new Error('bad status code: ' + res.statusCode) var error = Error('bad status code: ' + res.statusCode)
error.status = res.statusCode error.remoteStatus = res.statusCode
return callback(error) return callback(error)
} }
callback(null, body, res.headers.etag) callback(null, body, res.headers.etag)
@ -299,16 +296,10 @@ Storage.prototype.get_url = function(url) {
rstream.on('response', function(res) { rstream.on('response', function(res) {
if (res.statusCode === 404) { if (res.statusCode === 404) {
return stream.emit('error', new UError({ return stream.emit('error', Error[404]("file doesn't exist on uplink"))
message: 'file doesn\'t exist on uplink',
status: 404,
}))
} }
if (!(res.statusCode >= 200 && res.statusCode < 300)) { if (!(res.statusCode >= 200 && res.statusCode < 300)) {
return stream.emit('error', new UError({ return stream.emit('error', Error('bad uplink status code: ' + res.statusCode))
message: 'bad uplink status code: ' + res.statusCode,
status: 500,
}))
} }
if (res.headers['content-length']) { if (res.headers['content-length']) {
expected_length = res.headers['content-length'] expected_length = res.headers['content-length']
@ -327,7 +318,7 @@ Storage.prototype.get_url = function(url) {
rstream.on('end', function(d) { rstream.on('end', function(d) {
if (d) current_length += d.length if (d) current_length += d.length
if (expected_length && current_length != expected_length) if (expected_length && current_length != expected_length)
stream.emit('error', new Error('content length mismatch')) stream.emit('error', Error('content length mismatch'))
}) })
return stream return stream
} }

@ -28,6 +28,7 @@ dependencies:
cookies: '>=0.5.0 <1.0.0-0' cookies: '>=0.5.0 <1.0.0-0'
request: '>=2.31.0 <3.0.0-0' request: '>=2.31.0 <3.0.0-0'
async: '>=0.9.0 <1.0.0-0' async: '>=0.9.0 <1.0.0-0'
http-errors: '~1.2.0' # ferver
# 2.x and 3.x have the same interface # 2.x and 3.x have the same interface
semver: '>=2.2.1 <4.0.0-0' semver: '>=2.2.1 <4.0.0-0'