mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-13 01:31:22 +03:00
fix(ai): classify AWS modeled errors from every restJson1 identity location (#58770)
This commit is contained in:
committed by
GitHub
Unverified
parent
bd2ba0a685
commit
252ed4a2d8
@@ -250,6 +250,7 @@ export function classifyProviderFailure(input: ProviderFailure): AIError["reason
|
||||
...providerCodes(body),
|
||||
...providerCodes(input.message),
|
||||
...(GATEWAY_CODE_LABEL.exec(input.message)?.slice(1) ?? []),
|
||||
...awsErrorType(input.http?.headers["x-amzn-errortype"]),
|
||||
].map((code) => code.toLowerCase())
|
||||
// Scan the raw payload too so signals missing from the summary message
|
||||
// (e.g. overflow phrases nested in a JSON error body) still classify.
|
||||
@@ -325,6 +326,8 @@ function providerCodes(value: unknown) {
|
||||
const exception = isRecord(decoded.exception) ? decoded.exception : undefined
|
||||
return [
|
||||
decoded.code,
|
||||
...awsErrorType(decoded.__type),
|
||||
...awsErrorType(decoded.code),
|
||||
// Stability's `{ id, name, errors }` bodies carry the code in `name`.
|
||||
Array.isArray(decoded.errors) ? decoded.name : undefined,
|
||||
decoded.error_type,
|
||||
@@ -343,3 +346,10 @@ function providerCodes(value: unknown) {
|
||||
exception?.type,
|
||||
].filter((value): value is string => typeof value === "string")
|
||||
}
|
||||
|
||||
// AWS restJson1 reports the modeled error in `X-Amzn-Errortype`, `__type` or `code`, possibly
|
||||
// namespaced (`ns#Name`) or suffixed (`Name:uri`). Keep the shape name only.
|
||||
// https://smithy.io/2.0/aws/protocols/aws-restjson1-protocol.html#operation-error-serialization
|
||||
function awsErrorType(value: unknown) {
|
||||
return typeof value === "string" ? [value.replace(/:.*/s, "").replace(/^[^#]*#/, "")] : []
|
||||
}
|
||||
|
||||
@@ -75,6 +75,29 @@ describe("RequestExecutor", () => {
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("classifies AWS modeled errors from every restJson1 identity location", () =>
|
||||
Effect.sync(() => {
|
||||
const cases = [
|
||||
{ body: { code: "ThrottlingException" } },
|
||||
{ body: { __type: "ThrottlingException" } },
|
||||
{ body: { code: "com.amazonaws.bedrock#ThrottlingException:http://internal.amazon.com/coral/" } },
|
||||
{ body: {}, headers: { "X-Amzn-Errortype": "ThrottlingException:http://internal.amazon.com/coral/" } },
|
||||
]
|
||||
for (const item of cases) {
|
||||
const body = JSON.stringify({ ...item.body, message: "Slow down" })
|
||||
const error = RequestExecutor.httpFailure({
|
||||
message: "Slow down",
|
||||
url: request.url,
|
||||
status: 400,
|
||||
responseHeaders: item.headers,
|
||||
responseBody: body,
|
||||
})
|
||||
expect(error.reason._tag).toBe("RateLimit")
|
||||
expect(error.reason.body).toBe(body)
|
||||
}
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("retains the original body-read failure on an HTTP status error", () =>
|
||||
Effect.gen(function* () {
|
||||
const cause = new Error("response body disconnected")
|
||||
|
||||
Reference in New Issue
Block a user