diff --git a/server/src/services/contractErrors.test.ts b/server/src/services/contractErrors.test.ts new file mode 100644 index 0000000..73cb92f --- /dev/null +++ b/server/src/services/contractErrors.test.ts @@ -0,0 +1,15 @@ +import { ContractError, TradeNotFoundError, UnauthorizedContractError, parseContractError } from "./contractErrors"; + +describe("contract error mapping", () => { + it("maps Soroban numeric codes to actionable typed errors", () => { + expect(parseContractError(new Error("Error(Contract, #3)"))).toBeInstanceOf(TradeNotFoundError); + expect(parseContractError("ContractError(2)")).toBeInstanceOf(UnauthorizedContractError); + }); + + it("uses a safe typed fallback for unknown codes and unrelated failures", () => { + const unknown = parseContractError("Error(Contract, #999)"); + expect(unknown).toBeInstanceOf(ContractError); + expect(unknown?.message).toContain("could not be completed"); + expect(parseContractError(new Error("network unavailable"))).toBeNull(); + }); +}); diff --git a/server/src/services/contractErrors.ts b/server/src/services/contractErrors.ts index f8f93d2..26e01f0 100644 --- a/server/src/services/contractErrors.ts +++ b/server/src/services/contractErrors.ts @@ -339,5 +339,5 @@ function instantiate(code: number): ContractError { return new Ctor(); } // Unknown code — return a generic ContractError so callers still get a typed object - return new ContractError(`Unknown contract error (code ${code})`, code); + return new ContractError("The transaction could not be completed. Please try again or contact support.", code); }