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

Custom error from createConnection makes it hard to get the response status/code #70

Open
ckcr4lyf opened this issue May 12, 2022 · 7 comments
Labels
enhancement New feature or request

Comments

@ckcr4lyf
Copy link
Contributor

Currently, if a CONNECT to the proxy fails, the error returned is using a vanilla Error with string templating to add the status code

callback(new Error(`Bad response: ${response.statusCode}`), null)

This means that from within the axios logic to send a request, if the proxy connection fails, it is not as trivial to extract the response status. Example with wrong credentials, using axios + hpagent:

image

For axios errors, the statusCode is typically in response.status, but since this is a custom error, that field is undefined. Since got, axios etc. have their own ways of handling errors, specifically what the field for the statusCode is called, maybe an hpagent extension to the error object, containing the code, and a boolean, isHpagentError: true ?

Otherwise currently I need to extract the response code from the string. I would be happy to make a PR for this if we can align on a way to pass this information

@delvedor
Copy link
Owner

Hello! I don't like the approach of adding a custom boolean to identify the error.
If we have to do this, it should follow Node.js's error conventions.

It could be something like:

class HPAError extends Error {
  constructor (message, statusCode) {
    super(message)
    this.name = 'HPAError'
    this.code = 'HPA_ERR_STATUS'
    this.statusCode = statusCode
  }
}

I fear this change would require a breaking change tho.

@delvedor delvedor added the enhancement New feature or request label May 12, 2022
@ckcr4lyf
Copy link
Contributor Author

ckcr4lyf commented May 12, 2022 via email

@delvedor
Copy link
Owner

I'm not sure, the following doesn't throw:

const assert = require('assert')

class HPAError extends Error {
  constructor (message, statusCode) {
    super(message)
    this.name = 'HPAError'
    this.code = 'HPA_ERR_STATUS'
    this.statusCode = statusCode
  }
}

const err = new HPAError('Bad response: 407', 407)
assert(err instanceof Error)
assert(err instanceof HPAError)
assert(err.message === 'Bad response: 407')

The issue could happen here:

assert(err.name === 'Error') // now `.name` is 'HPAError'

@ckcr4lyf
Copy link
Contributor Author

Ah right, this would mean changing the name property as well...

@mbargiel
Copy link
Contributor

mbargiel commented May 16, 2022

Have you considered replaying the proxy error response onto the socket, e.g. like it's done with https-proxy-agent? That allows the client to be completely unaware of proxies at all, so it goes ahead, sends its headers (ideally on a dummy, not-connected socket) and then reads the response status and headers back.

@mbargiel
Copy link
Contributor

I was going to open an issue for this, in fact - we would like our client to handle an HTTP response 407, not have to deal with knowing about hpagent as we intend to use it only indirectly through an HTTP library. (For context, I'm considering integrating hpagent into axios instead of using https-proxy-agent as I initially planned.)

@mbargiel
Copy link
Contributor

@delvedor I think I could open a PR for this. Would you take it?

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

No branches or pull requests

3 participants