-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors.ts
More file actions
47 lines (46 loc) · 2.13 KB
/
errors.ts
File metadata and controls
47 lines (46 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/**
* @fileoverview Named errors thrown by `github/*` helpers.
*/
/**
* Thrown by `fetchGitHub` when GitHub returns HTTP 200 OK with a
* zero-byte body — the "successful empty response" pattern.
*
* Why this exists (background for new contributors):
* GitHub's REST API has a documented failure mode that is *very*
* easy to miss in code review. During incidents where the search
* / Elasticsearch backing index is degraded (see GitHub status
* pages with titles like "search is degraded" or "Pull Requests
* degraded"), the REST `/repos/...` GET endpoints return:
* - HTTP status: 200 OK ← looks like success
* - Body: "" ← but the payload is empty
* - Headers: no Retry-After, no rate-limit signal, nothing
*
* Without a typed error, calling code does
* `JSON.parse(response.body.toString('utf8'))`
* on an empty string, which throws a confusing
* `SyntaxError: Unexpected end of JSON input`. That error has
* nothing to do with bad code on our side; it's GitHub's incident
* manifesting as a parse failure several frames deep. We surface
* the actual condition (`200 + empty body`) as its own typed
* exception so the call path can either fall through to the
* GraphQL backend (which queries a different data path and uses
* a different backend and is unaffected by ES outages), or surface
* a clean message to the user.
*
* The HTTP status is hard-coded to 200 because that's *exactly*
* what makes this insidious — a real 4xx/5xx would already be
* handled by the rate-limit / status-code branch above.
*/
export class GitHubEmptyBodyError extends Error {
/** HTTP status (always 200 — that's what makes this case insidious). */
status: number
constructor(url: string) {
// Library-API error: terse and stable so callers can switch on
// .name / instanceof without parsing the message. The verbose
// background ("documented incident shape", status URL) lives in
// the JSDoc above the class declaration.
super(`GitHub API returned HTTP 200 with empty body: ${url}`)
this.name = 'GitHubEmptyBodyError'
this.status = 200
}
}