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

feat: add more context for Request/Connect/DNSTimeoutErrors #109

Merged
merged 8 commits into from Feb 22, 2018

Conversation

DonutEspresso
Copy link
Member

Addresses #104.

Here are example errors of both classes:

{ ConnectTimeoutError: GET request to http://169.254.1.10/foo?a=1 failed to obtain connected socket within 100ms
    at buildConnectTimeoutError (/Users/aliu/Sandbox/restify-clients/lib/HttpClient.js:153:12)
    at Timeout.connectTimeout [as _onTimeout] (/Users/aliu/Sandbox/restify-clients/lib/HttpClient.js:231:23)
    at ontimeout (timers.js:365:14)
    at tryOnTimeout (timers.js:237:5)
    at Timer.listOnTimeout (timers.js:207:5)
  name: 'ConnectTimeoutError',
  jse_shortmsg: 'GET request to http://169.254.1.10/foo?a=1 failed to obtain connected socket within 100ms',
  jse_info: { fullUrl: 'http://169.254.1.10/foo?a=1', connectTimeout: 100 },
  message: 'GET request to http://169.254.1.10/foo?a=1 failed to obtain connected socket within 100ms' }
{ RequestTimeoutError: GET request to http://127.0.0.1:53927/str/request_timeout failed to complete within 150ms
    at buildRequestTimeoutError (/Users/aliu/Sandbox/restify-clients/lib/HttpClient.js:124:12)
    at Timeout.requestTimeout [as _onTimeout] (/Users/aliu/Sandbox/restify-clients/lib/HttpClient.js:383:31)
    at ontimeout (timers.js:365:14)
    at tryOnTimeout (timers.js:237:5)
    at Timer.listOnTimeout (timers.js:207:5)
  name: 'RequestTimeoutError',
  jse_shortmsg: 'GET request to http://127.0.0.1:53927/str/request_timeout failed to complete within 150ms',
  jse_info:
   { fullUrl: 'http://127.0.0.1:53927/str/request_timeout',
     requestTimeout: 150 },
  message: 'GET request to http://127.0.0.1:53927/str/request_timeout failed to complete within 150ms' }

I'm looking for feedback on two items:

  1. Do we want to attach more fields onto the verror infoobject? The full URL can be parsed by url.parse() to get any of the derived fields (hostname, path, protocol, port, etc.) but I'm happy to directly attach the results of url.parse() to the info object as well.

  2. The initial feedback in connection-related errors could provide more information #104 sounded like we might want to have an underlying error which could be used as a cause for ConnectTimeout or RequestTimeout - but both of these seem pretty low level as is, so I decided to just attach the relevant metadata directly into info object. Would be happy to hear alternative approaches here.

package.json Outdated
@@ -48,7 +48,7 @@
"coveralls": "^2.11.4",
"eslint": "^3.1.0",
"istanbul": "^0.4.0",
"jscs": "^3.0.0",
"jscs": "^2.11.0",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jscs@3.x was hanging for some reason on OSX, and I'm not inclined to spend time trying to figure out why, since it is deprecated already.

@coveralls
Copy link

Coverage Status

Coverage increased (+0.2%) to 84.605% when pulling bbfd640 on verror-info into 85374f8 on master.

@coveralls
Copy link

coveralls commented Feb 13, 2017

Coverage Status

Coverage increased (+0.6%) to 86.759% when pulling cfdc819 on verror-info into e0f36ef on master.

@DonutEspresso
Copy link
Member Author

@davepacheco took a stab using the initial feedback in your issue. There are some open questions though, would appreciate your thoughts.

// as TooManyRedirects. This has been rectified as TooManyRequests.
// in the case of restify-clients, we will retain this error type given that
// users can specify maximum number of redirects to follow.
if (!errors.TooManyRedirectsError) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hasn't changed, I just moved it to the top of the file after the global requires and before function declarations. Also added a comment.

@davepacheco
Copy link

This looks great! Thanks for providing all the notes about the change. The one extra thing it would be nice to have as an informational property is the request method, since you can't get that from the fullUrl.

Also: if you make a request to a DNS name that was resolved to a specific IP address, is this going to show up in fullUrl using the DNS name or the IP address? We usually find that both are pretty valuable, but the IP address is probably more valuable if we have to choose (because we can figure out what service it was part of if we have the IP, but if we have the DNS name, we can never figure out which instance it was).

Related to #104: there's still the problem that this may not be a connection timeout at all, but rather a DNS timeout. I'm not sure if the name can be changed in a compatible way, but at least the message reflects what really happened here.

Thanks again for doing this. It's going to be a huge help for us.

@davepacheco
Copy link

Another thing that would be nice in the VError info is the socket's source IP and port so that we can correlate these issues with logs on the server side (even in the case of a connect timeout, because it's possible we handled this connection, only after the client gave up on it).

@DonutEspresso
Copy link
Member Author

DonutEspresso commented Feb 18, 2018

Sorry for dropping the ball on this! Circled back around and made all the proposed changes, including #111. There are now 3 errors depending on when things go awry: DNSTimeoutError, ConnectTimeoutError, and RequestTimeoutError.

All errors return the following fields on the info object: address, fullUrl, method, port, as well as the timeout value that triggered the error.

@DonutEspresso DonutEspresso requested review from retrohacker, hekike and rajatkumar and removed request for micahr and yunong February 18, 2018 04:36
@DonutEspresso DonutEspresso changed the title add more context for request and connect timeout errors new: add more context for Request/Connect/DNSTimeoutErrors Feb 18, 2018
@DonutEspresso
Copy link
Member Author

I forgot to add - tests won't pass here until restify/errors#86 lands, as we need to standardize on the use of VError (and .info) across all created error types before this PR can work as intended.

// jscs:disable maximumLineLength
var VERSION = JSON.parse(fs.readFileSync(path.join(__dirname, './../package.json'), 'utf8')).version;
// jscs:enable maximumLineLength
var VERSION = JSON.parse(fs.readFileSync(
Copy link
Member

@hekike hekike Feb 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can require .json files directly:

var VERSION = require(path.join(__dirname, './../package.json')).version;

* @function createConnectTimeoutErr
* @param {Object} opts options object for a request
* @param {Object} req the request object
* @returns {Object} ConnectionTimeoutError
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about? @returns {verror.VError} ConnectionTimeoutError

* @function createRequestTimeoutErr
* @param {Object} opts options object for a request
* @param {Object} req the request object
* @returns {Object} RequestTimeoutError
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about? @returns {verror.VError} ConnectionTimeoutError




function createTooManyRedirectsErr(opts, req) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing JSDoc

* logging/visibility.
* @private
* @function fullRequestUrl
* @param {Object} opts request options
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing JSDoc: options breakdown

Copy link
Member

@hekike hekike left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice PR, some smaller JSDoc issues

@DonutEspresso
Copy link
Member Author

Thanks @hekike, all feedback addressed! Also updated package.json to point restify-errors at the commit needed so that tests will pass. Will point that to latest once a new version is published.

@@ -21,7 +21,6 @@ var REST_CODES = [
{ name: 'InvalidVersionError', code: 400 },
{ name: 'MissingParameterError', code: 409 },
{ name: 'NotAuthorizedError', code: 403 },
{ name: 'PreconditionFailedError', code: 412 },
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests were added to ensure that changes in restify-error didn't break this repo. Since restify-errors is a breaking change, these tests had to be updated (arguably these tests should not belong in this repo, but don't recall the history here).

Copy link
Member

@retrohacker retrohacker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me!

@DonutEspresso DonutEspresso changed the title new: add more context for Request/Connect/DNSTimeoutErrors feat: add more context for Request/Connect/DNSTimeoutErrors Feb 21, 2018
@DonutEspresso
Copy link
Member Author

Bunch of work to rebase master. Once tests pass, this is good to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants