-module(aws@internal@error_code). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/aws/internal/error_code.gleam"). -export([normalise/1, from_header_value_and_body/2, from_headers_and_body/2]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC( " Shared modeled-error-code extraction. AWS error responses carry the\n" " modeled error *code* (the Smithy shape's local name) in one of three\n" " places, depending on protocol: the `X-Amzn-Errortype` header\n" " (awsJson*, restJson1), a JSON body `__type` / `code` field, or a\n" " restXml `` element. This module pulls that local shape name\n" " out — namespace prefix, URI suffix, and Smithy `[Charlie,foo]`\n" " disambiguation suffix all stripped.\n" "\n" " Both the retry middleware (`aws/retry`), which inspects the raw\n" " `Response` *inside* the retry loop before any typed parsing, and the\n" " runtime (`aws/internal/client/runtime`), which builds the typed\n" " `ServiceError` *after* the loop, need the same extraction — so it\n" " lives here once rather than being duplicated across the two layers.\n" ). -file("src/aws/internal/error_code.gleam", 57). ?DOC( " Strip an error-type wire value down to its local Smithy shape name:\n" " drop any `Type:uri` suffix, any `,` disambiguation list, and any\n" " `namespace#` prefix. Exposed so callers that already hold a raw\n" " header value (not a full response) can normalise it consistently.\n" ). -spec normalise(binary()) -> binary(). normalise(Raw) -> S = case gleam@string:split_once(Raw, <<":"/utf8>>) of {ok, {Prefix, _}} -> Prefix; {error, _} -> Raw end, S@1 = case gleam@string:split_once(S, <<","/utf8>>) of {ok, {Prefix@1, _}} -> Prefix@1; {error, _} -> S end, case gleam@string:split_once(S@1, <<"#"/utf8>>) of {ok, {_, Local}} -> Local; {error, _} -> S@1 end. -file("src/aws/internal/error_code.gleam", 90). ?DOC( " Pull the error code out of a restXml error body. Two shapes appear\n" " in the wild — S3-style `NoSuchBucket...`\n" " and SQS/SNS-style `X...`.\n" " In both, the first `` element holds the error type, so a\n" " single text search covers both without dragging in the full XML\n" " decoder. The trim + empty-check rejects `` / ` `\n" " so the fallback to \"Unknown\" still fires for malformed bodies.\n" ). -spec from_xml(binary()) -> {ok, binary()} | {error, nil}. from_xml(Body) -> gleam@result:'try'( aws@internal@text_scan:xml_tag_text(Body, <<"Code"/utf8>>), fun(Raw) -> case gleam@string:trim(Raw) of <<""/utf8>> -> {error, nil}; Non_empty -> {ok, Non_empty} end end ). -file("src/aws/internal/error_code.gleam", 72). -spec from_body(binary()) -> binary(). from_body(Body) -> Found = begin _pipe = aws@internal@text_scan:json_string_after_key( Body, <<"__type"/utf8>> ), _pipe@1 = gleam@result:lazy_or( _pipe, fun() -> aws@internal@text_scan:json_string_after_key( Body, <<"code"/utf8>> ) end ), gleam@result:lazy_or(_pipe@1, fun() -> from_xml(Body) end) end, case Found of {ok, V} -> normalise(V); {error, _} -> <<"Unknown"/utf8>> end. -file("src/aws/internal/error_code.gleam", 39). ?DOC( " Like `from_headers_and_body` but taking the `x-amzn-errortype`\n" " header value as a pre-resolved `Result`. The retry layer holds a\n" " `Response` (not a header dict) and reads the header via\n" " `response.get_header`, so this entry point lets it reuse the exact\n" " same extraction without rebuilding a dict.\n" ). -spec from_header_value_and_body({ok, binary()} | {error, nil}, bitstring()) -> binary(). from_header_value_and_body(Error_type_header, Body) -> case Error_type_header of {ok, V} -> normalise(V); {error, _} -> case gleam@bit_array:to_string(Body) of {error, _} -> <<"Unknown"/utf8>>; {ok, Text} -> from_body(Text) end end. -file("src/aws/internal/error_code.gleam", 27). ?DOC( " Pull the wire-error-type local name out of an error response's\n" " already-lowercased headers + body. Prefers the `x-amzn-errortype`\n" " header (restJson1, awsJson*), then falls back to the body's\n" " `__type` / `code` (JSON) or `` (restXml). Returns the *local*\n" " shape name with namespace / URI / disambiguation suffixes stripped,\n" " or `\"Unknown\"` when nothing matches.\n" ). -spec from_headers_and_body(gleam@dict:dict(binary(), binary()), bitstring()) -> binary(). from_headers_and_body(Headers, Body) -> from_header_value_and_body( gleam_stdlib:map_get(Headers, <<"x-amzn-errortype"/utf8>>), Body ).