Skip to content

feat: export upstream error status codes as UPSTREAM_ERROR_STATUS_CODE - #741

Open
bliuchak wants to merge 6 commits into
masterfrom
claude/affectionate-goodall-ej3ou0
Open

bliuchak wants to merge 6 commits into
masterfrom
claude/affectionate-goodall-ej3ou0

Conversation

@bliuchak

@bliuchak bliuchak commented Nov 7, 2026 •

Copy link
Copy Markdown
Contributor

Closes #593

What

Exports the custom 590–599 status codes from the package entry point as UPSTREAM_ERROR_STATUS_CODE, plus the UpstreamErrorStatusCode type for their values:

import { UPSTREAM_ERROR_STATUS_CODE } from 'proxy-chain';

if (response.status === UPSTREAM_ERROR_STATUS_CODE.AUTH_FAILED) {
    // Incorrect upstream proxy credentials
}

Why

The codes are already a documented public contract in the README, so consumers end up hard-coding them. Exporting the constant lets them reference the codes by name.

How

  • Renamed the internal badGatewayStatusCodes to UPSTREAM_ERROR_STATUS_CODE, following the constant naming in docs/agents/typescript.md.
  • Only 590–599 are exported. The 504 timeout code stays internal, because a target can return its own 504, which the proxy passes through, so clients could not tell the two apart.
  • Wrapped the object in Object.freeze, so a consumer can't change the codes the server itself responds with.
  • Only this constant and its type are exported. The other helpers in statuses.ts stay internal.
  • The README maps each key to its code. The STATUS_CODES reason phrases are now registered by key instead of repeating the numbers.

Risks

This only adds to the public API. Once released, renaming the constant or its keys would be a breaking change.

Testing

Type-check, lint, build and unit tests pass. The e2e suite fails the same 55 puppeteer and SOCKS tests with and without this change, in an environment without a browser or SOCKS upstream, and has no new failures.

https://claude.ai/code/session_01UdrrEDhY1FTbje75nFktTS


Generated by Claude Code

Export the custom 590-599 status code map from the package entry point so
consumers don't have to duplicate it. The object is frozen so that consumers
cannot change the codes the server itself responds with.

Closes #593

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UdrrEDr4ikhaZRb2M7jyM8
The map also holds 504 Gateway Timeout and describes upstream failures in
general, so the old name was misleading. Renamed before it becomes public.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UdrrEDr4ikhaZRb2M7jyM8
@apify-service-account apify-service-account added the tested Temporary label used only programatically for some analytics. label Nov 7, 2026
@apify-service-account apify-service-account added the t-unblocking Issues with this label are in the ownership of the unblocking team. label Nov 7, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UdrrEDr4ikhaZRb2M7jyM8
- Add and export an UpstreamErrorStatusCode type for the code values,
  and use it for errorCodeToStatusCode and socksErrorMessageToStatusCode.
- Drop the redundant `as const` next to Object.freeze and the no-op one
  on errorCodeToStatusCode.
- Register the STATUS_CODES reason phrases by key instead of repeating
  the numbers.
- Document every key, including TIMEOUT (504), in the README.
- Note the selective statuses.ts export in docs/agents/architecture.md.
- Name the unit tests after what they check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UdrrEDhY1FTbje75nFktTS
- Rename the exported constant to UPSTREAM_ERROR_STATUS_CODE, following
  the SCREAMING_SNAKE, singular and ValueOf conventions in
  docs/agents/typescript.md.
- Drop TIMEOUT (504) from the exported constant. A target can return its
  own 504, which the proxy passes through, so clients could not tell the
  two apart. The timeout code stays internal.
- Update the README table, the unit test and the architecture notes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UdrrEDhY1FTbje75nFktTS
@bliuchak bliuchak changed the title feat: export upstreamErrorStatusCodes feat: export upstream error status codes as UPSTREAM_ERROR_STATUS_CODE Nov 9, 2026
Replace the hard-coded 590-599 values in the e2e tests with the exported
constant. The unit test keeps the literal values, since it pins the
published codes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UdrrEDhY1FTbje75nFktTS

@daniil-poletaev daniil-poletaev left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good!

Just 1 thing:
new UpstreamErrorStatusCode type doesn't include 504, but the server still returns 504 when an upstream proxy times out. Is it intended?

bliuchak commented Nov 9, 2026

Copy link
Copy Markdown
Contributor Author

Yes, leaving 504 out is intentional. The proxy still returns 504 when an upstream proxy times out, but only internally, through UPSTREAM_TIMEOUT_STATUS_CODE in src/statuses.ts.

It isn't exported because a target server can send its own 504, and the proxy passes that through unchanged. A client that sees 504 therefore can't tell an upstream proxy timeout from the target's own gateway timeout. Treating it as an upstream error would be wrong some of the time.

UPSTREAM_ERROR_STATUS_CODE and UpstreamErrorStatusCode only cover 590–599. The proxy is the only thing that sends those codes, so a client can rely on them. 504 keeps its standard HTTP meaning.


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-unblocking Issues with this label are in the ownership of the unblocking team. tested Temporary label used only programatically for some analytics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Export badGatewayStatusCodes

5 participants