Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing Error.name for thrown errors #463

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
69 changes: 54 additions & 15 deletions main.js
Expand Up @@ -139,7 +139,9 @@ Request.prototype.init = function (options) {


if (!self.uri) { if (!self.uri) {
// this will throw if unhandled but is handleable when in a redirect // this will throw if unhandled but is handleable when in a redirect
return self.emit('error', new Error("options.uri is a required argument")) var error = new Error('options.uri is a required argument')
error.name = 'ArgumentError'
return self.emit('error', error)
} else { } else {
if (typeof self.uri == "string") self.uri = url.parse(self.uri) if (typeof self.uri == "string") self.uri = url.parse(self.uri)
} }
Expand Down Expand Up @@ -168,14 +170,15 @@ Request.prototype.init = function (options) {
// Invalid URI: it may generate lot of bad errors, like "TypeError: Cannot call method 'indexOf' of undefined" in CookieJar // Invalid URI: it may generate lot of bad errors, like "TypeError: Cannot call method 'indexOf' of undefined" in CookieJar
// Detect and reject it as soon as possible // Detect and reject it as soon as possible
var faultyUri = url.format(self.uri) var faultyUri = url.format(self.uri)
var message = 'Invalid URI "' + faultyUri + '"' var error = new Error('Invalid URI "' + faultyUri + '"')
if (Object.keys(options).length === 0) { if (Object.keys(options).length === 0) {
// No option ? This can be the sign of a redirect // No option ? This can be the sign of a redirect
// As this is a case where the user cannot do anything (he didn't call request directly with this URL) // As this is a case where the user cannot do anything (he didn't call request directly with this URL)
// he should be warned that it can be caused by a redirection (can save some hair) // he should be warned that it can be caused by a redirection (can save some hair)
message += '. This can be caused by a crappy redirection.' error.message += '. This can be caused by a crappy redirection.'
} }
self.emit('error', new Error(message)) error.name = 'URIError'
self.emit('error', error)
return // This error was fatal return // This error was fatal
} }


Expand Down Expand Up @@ -229,10 +232,12 @@ Request.prototype.init = function (options) {
clearTimeout(self.timeoutTimer) clearTimeout(self.timeoutTimer)
self.timeoutTimer = null self.timeoutTimer = null
} }
error.name = 'ClientError'
self.emit('error', error) self.emit('error', error)
} }


self._parserErrorHandler = function (error) { self._parserErrorHandler = function (error) {
error.name = 'ParseError'
if (this.res) { if (this.res) {
if (this.res.request) { if (this.res.request) {
this.res.request.emit('error', error) this.res.request.emit('error', error)
Expand Down Expand Up @@ -310,7 +315,9 @@ Request.prototype.init = function (options) {
if(!self.headers['content-length'] && !self.headers['Content-Length']) if(!self.headers['content-length'] && !self.headers['Content-Length'])
self.headers['content-length'] = length self.headers['content-length'] = length
} else { } else {
throw new Error('Argument error, options.body.') var error = new Error('Argument error, options.body.')
error.name = 'ArgumentError'
throw error
} }
} }


Expand All @@ -320,7 +327,11 @@ Request.prototype.init = function (options) {
; ;
self.httpModule = httpModules[protocol] || defaultModules[protocol] self.httpModule = httpModules[protocol] || defaultModules[protocol]


if (!self.httpModule) return this.emit('error', new Error("Invalid protocol")) if (!self.httpModule) {
var error = new Error('Invalid protocol')
error.name = 'URIError'
return this.emit('error', error)
}


if (options.ca) self.ca = options.ca if (options.ca) self.ca = options.ca


Expand Down Expand Up @@ -351,7 +362,11 @@ Request.prototype.init = function (options) {
} }


self.once('pipe', function (src) { self.once('pipe', function (src) {
if (self.ntick && self._started) throw new Error("You cannot pipe to this stream after the outbound request has started.") if (self.ntick && self._started) {
var error = new Error('You cannot pipe to this stream after the outbound request has started.')
error.name = 'PipeError'
throw error
}
self.src = src self.src = src
if (isReadStream(src)) { if (isReadStream(src)) {
if (!self.headers['content-type'] && !self.headers['Content-Type']) if (!self.headers['content-type'] && !self.headers['Content-Type'])
Expand Down Expand Up @@ -879,15 +894,23 @@ Request.prototype.multipart = function (multipart) {
self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=' + self.boundary self.headers['content-type'] = self.headers['content-type'].split(';')[0] + '; boundary=' + self.boundary
} }


if (!multipart.forEach) throw new Error('Argument error, options.multipart.') if (!multipart.forEach) {
var error = new Error('Argument error, options.multipart.')
error.name = 'ArgumentError'
throw error
}


if (self.preambleCRLF) { if (self.preambleCRLF) {
self.body.push(new Buffer('\r\n')) self.body.push(new Buffer('\r\n'))
} }


multipart.forEach(function (part) { multipart.forEach(function (part) {
var body = part.body var body = part.body
if(body == null) throw Error('Body attribute missing in multipart.') if(body == null) {
var error = new Error('Body attribute missing in multipart.')
error.name = 'ArgumentError'
throw error
}
delete part.body delete part.body
var preamble = '--' + self.boundary + '\r\n' var preamble = '--' + self.boundary + '\r\n'
Object.keys(part).forEach(function (key) { Object.keys(part).forEach(function (key) {
Expand Down Expand Up @@ -926,7 +949,9 @@ function getHeader(name, headers) {
} }
Request.prototype.auth = function (user, pass, sendImmediately) { Request.prototype.auth = function (user, pass, sendImmediately) {
if (typeof user !== 'string' || typeof pass !== 'string') { if (typeof user !== 'string' || typeof pass !== 'string') {
throw new Error('auth() received invalid user or password') var error = new Error('auth() received invalid user or password')
error.name = 'ArgumentError'
throw error
} }
this._user = user this._user = user
this._pass = pass this._pass = pass
Expand Down Expand Up @@ -1053,9 +1078,13 @@ Request.prototype.jar = function (jar) {
Request.prototype.pipe = function (dest, opts) { Request.prototype.pipe = function (dest, opts) {
if (this.response) { if (this.response) {
if (this._destdata) { if (this._destdata) {
throw new Error("You cannot pipe after data has been emitted from the response.") var error = new Error('You cannot pipe after data has been emitted from the response.')
error.name = 'PipeError'
throw error
} else if (this._ended) { } else if (this._ended) {
throw new Error("You cannot pipe after the response has been ended.") var error = new Error('You cannot pipe after the response has been ended.')
error.name = 'PipeError'
throw error
} else { } else {
stream.Stream.prototype.pipe.call(this, dest, opts) stream.Stream.prototype.pipe.call(this, dest, opts)
this.pipeDest(dest) this.pipeDest(dest)
Expand Down Expand Up @@ -1103,7 +1132,11 @@ function initParams(uri, options, callback) {
} }


function request (uri, options, callback) { function request (uri, options, callback) {
if (typeof uri === 'undefined') throw new Error('undefined is not a valid uri or options object.') if (typeof uri === 'undefined') {
var error = new Error('undefined is not a valid uri or options object.')
error.name = 'URIError'
throw error
}
if ((typeof options === 'function') && !callback) callback = options if ((typeof options === 'function') && !callback) callback = options
if (options && typeof options === 'object') { if (options && typeof options === 'object') {
options.uri = uri options.uri = uri
Expand Down Expand Up @@ -1189,7 +1222,9 @@ request.head = function (uri, options, callback) {
params.options.requestBodyStream || params.options.requestBodyStream ||
(params.options.json && typeof params.options.json !== 'boolean') || (params.options.json && typeof params.options.json !== 'boolean') ||
params.options.multipart) { params.options.multipart) {
throw new Error("HTTP HEAD requests MUST NOT include a request body.") var error = new Error('HTTP HEAD requests MUST NOT include a request body.')
error.name = 'ArgumentError'
throw error
} }
return request(params.uri || null, params.options, params.callback) return request(params.uri || null, params.options, params.callback)
} }
Expand All @@ -1206,7 +1241,11 @@ request.jar = function () {
} }
request.cookie = function (str) { request.cookie = function (str) {
if (str && str.uri) str = str.uri if (str && str.uri) str = str.uri
if (typeof str !== 'string') throw new Error("The cookie function only accepts STRING as param") if (typeof str !== 'string') {
var error = new Error('The cookie function only accepts STRING as param')
error.name = 'ArgumentError'
throw error
}
return new Cookie(str) return new Cookie(str)
} }


Expand Down
2 changes: 2 additions & 0 deletions tunnel.js
Expand Up @@ -147,6 +147,7 @@ TunnelingAgent.prototype.createSocket = function createSocket(options, cb) {
debug('tunneling socket could not be established, statusCode=%d', res.statusCode) debug('tunneling socket could not be established, statusCode=%d', res.statusCode)
var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode) var error = new Error('tunneling socket could not be established, ' + 'statusCode=' + res.statusCode)
error.code = 'ECONNRESET' error.code = 'ECONNRESET'
error.name = 'ConnectionError'
options.request.emit('error', error) options.request.emit('error', error)
self.removeSocket(placeholder) self.removeSocket(placeholder)
} }
Expand All @@ -158,6 +159,7 @@ TunnelingAgent.prototype.createSocket = function createSocket(options, cb) {
debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack) debug('tunneling socket could not be established, cause=%s\n', cause.message, cause.stack)
var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message) var error = new Error('tunneling socket could not be established, ' + 'cause=' + cause.message)
error.code = 'ECONNRESET' error.code = 'ECONNRESET'
error.name = 'ConnectionError'
options.request.emit('error', error) options.request.emit('error', error)
self.removeSocket(placeholder) self.removeSocket(placeholder)
} }
Expand Down