Issue title: Exception thrown on request time out
 Issue body: There is the potential for an exception to be thrown when a request times out and the timeout property has been set in the request options. Node (v0.6.17) will still exit even if the exception is caught.

Potential source of the callback error is at https://github.com/mikeal/request/blob/master/main.js#L654

In the call that caused the problem, the options are:

``` javascript
var pageRequest = {
    method: 'GET',
    url: url,
    timeout: 10000,
    followRedirect: false,
    jar: request.jar(),
    headers: { 'user-agent': 'GoInstantCrawler/1.0' }  };
```

And the call itself was done as follows:

``` javascript
  var fetchRequest = request.get(pageRequest, function(err, resp, body) {
    try {
      if (err) return logFetchFailure(err, pageRequest, cb);
      if (!resp) return logFetchFailure(new Error("No response body from fetch page request"), pageRequest, cb);

      var contentType = resp.headers['content-type'];
      DBG&&DBG('page fetched', pageRequest.url,
                'status code', resp.statusCode,
                'content-type', contentType,
                'body length', body ? body.length : 'n/a');

      // Handle a redirected page
      if (resp.statusCode === 301 || resp.statusCode === 302 || resp.statusCode === 303) {
        return handleUrlRedirect(pageRequest, resp.headers.location, cb);

      // Handle a normaly returned page
      } else if (resp.statusCode === 200) {
        if (!body || body.length === 0) return logFetchFailure(new Error("URL fetch returned an empty body."), pageRequest, cb);

        // This is the "success" condition where a body is returned and needs to be processed.
        cb(null, pageRequest, contentType, body);

      // All other status codes (unhandled).
      } else {
        return logFetchFailure(new Error("URL fetch returned an unprocessable return code: " + resp.statusCode), pageRequest, cb);
      }

    } catch(e) {
      DBG&&DBG("Unhandled exception caught in fetchPage",
               "Fetching URL: ", pageRequest.url,
               "Exception: ", e);

      return logFetchFailure(e, pageRequest, cb);
    }
  });
```

The pattern of failure typically has one URL fail with the ETIMEOUT error and then the next URL fail with the ESOCKETTIMEDOUT error. A typical dump from the program is as follows (the initial text comes from the logFetchFailure method referenced in the above code snippet):

```
Page fetch failed http://mentaltrackmarks.com/?tag=enniscrone  with error: { [Error: ETIMEDOUT] code: 'ETIMEDOUT' }
Page fetch failed http://mentaltrackmarks.com/?tag=dublin  with error: { [Error: ESOCKETTIMEDOUT] code: 'ESOCKETTIMEDOUT' }

node.js:201
        throw e; // process.nextTick error, or 'error' event on first tick
              ^
Error: timeout
    at ClientRequest.emitTimeout (http.js:1346:18)
    at ClientRequest.g (events.js:156:14)
    at ClientRequest.emit (events.js:88:20)
    at Socket.emitTimeout (http.js:1345:10)
    at Socket.g (events.js:156:14)
    at Socket.emit (events.js:64:17)
    at Socket._onTimeout (net.js:153:8)
    at Timer.ontimeout (timers.js:94:19)
```

 Comments: 
 Comment 0: 'complete' is typically a handler for the callback passed to request, so if there is another exception in that callback it's happening in the function you pass to request, not one that is part of the request source.

{'source': 'GithubIssues', 'repo_name_with_owner': 'request/request', 'issue_id': 6378224, 'repo_stars': 25558.0}