diff --git a/sdks/typescript/pmxt/hosted-routing.ts b/sdks/typescript/pmxt/hosted-routing.ts index 09fec8fb..cf8cd8bf 100644 --- a/sdks/typescript/pmxt/hosted-routing.ts +++ b/sdks/typescript/pmxt/hosted-routing.ts @@ -156,11 +156,21 @@ export async function _tradingRequest( body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined, }); + const text = await resp.text(); + if (!resp.ok) { - await raiseFromResponse(resp); + await raiseFromResponse(new Response(text, { status: resp.status, statusText: resp.statusText })); } - const text = await resp.text(); if (!text) return null; - return JSON.parse(text); + const payload = JSON.parse(text); + if ( + payload != null && + typeof payload === "object" && + ((payload as Record).success === false || + typeof (payload as Record).error === "string") + ) { + await raiseFromResponse(new Response(text, { status: resp.status, statusText: resp.statusText })); + } + return payload; } diff --git a/sdks/typescript/tests/hosted-routing-embedded-error.test.ts b/sdks/typescript/tests/hosted-routing-embedded-error.test.ts new file mode 100644 index 00000000..51b15d6e --- /dev/null +++ b/sdks/typescript/tests/hosted-routing-embedded-error.test.ts @@ -0,0 +1,34 @@ +import { _tradingRequest } from "../pmxt/hosted-routing"; +import { HostedTradingError } from "../pmxt/hosted-errors"; + +const client = { pmxtApiKey: "test_pmxt_key", exchangeName: "polymarket" }; + +afterEach(() => { + jest.restoreAllMocks(); +}); + +function installFetchResponse(payload: unknown, status = 200): jest.SpyInstance { + return jest.spyOn(global, "fetch").mockResolvedValue( + new Response(JSON.stringify(payload), { + status, + headers: { "Content-Type": "application/json" }, + }), + ); +} + +describe("_tradingRequest embedded error envelopes", () => { + it("raises a hosted error for 2xx responses with success=false", async () => { + installFetchResponse({ success: false, error: "upstream rejected order" }, 200); + + try { + await _tradingRequest(client, { method: "GET", path: "/v0/user/me/balances" }); + } catch (err) { + expect(err).toBeInstanceOf(HostedTradingError); + expect((err as HostedTradingError).status).toBe(200); + expect((err as HostedTradingError).detail).toBe("upstream rejected order"); + return; + } + + throw new Error("expected _tradingRequest to raise HostedTradingError"); + }); +});