error.test.ts 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import { describe, expect, test } from "bun:test"
  2. import { errorData, errorFormat, errorMessage } from "../../src/util/error"
  3. describe("util.error", () => {
  4. test("keeps the server error reference available for log correlation", () => {
  5. const error = {
  6. name: "UnknownError",
  7. data: {
  8. message: "Unexpected server error. Check server logs for details.",
  9. ref: "err_1234abcd",
  10. },
  11. }
  12. expect(errorMessage(error)).toBe(
  13. "Unexpected server error. Check server logs for details.\nError reference: err_1234abcd",
  14. )
  15. expect(errorMessage(new Error("HTTP request failed", { cause: { body: error } }))).toBe(errorMessage(error))
  16. expect(errorData(error).message).toContain("err_1234abcd")
  17. })
  18. test("explains provider configuration errors instead of displaying an opaque object", () => {
  19. expect(
  20. errorMessage({
  21. name: "ProviderModelNotFoundError",
  22. data: { providerID: "test", modelID: "missing", suggestions: ["available"] },
  23. }),
  24. ).toContain("Did you mean: available")
  25. expect(errorMessage({ name: "UnknownError", data: { message: "failure" } })).toBe("failure")
  26. })
  27. test("formats native Error instances", () => {
  28. const err = new Error("boom")
  29. expect(errorMessage(err)).toBe("boom")
  30. expect(errorFormat(err)).toContain("boom")
  31. const data = errorData(err)
  32. expect(data.type).toBe("Error")
  33. expect(data.message).toBe("boom")
  34. expect(String(data.formatted)).toContain("boom")
  35. })
  36. test("extracts message from record-like values", () => {
  37. const err = { message: "bad input", code: "E_BAD" }
  38. expect(errorMessage(err)).toBe("bad input")
  39. const data = errorData(err)
  40. expect(data.message).toBe("bad input")
  41. expect(data.code).toBe("E_BAD")
  42. })
  43. test("never returns bare {} for opaque object errors", () => {
  44. expect(errorFormat({})).not.toBe("{}")
  45. expect(errorFormat({})).toContain("no message")
  46. class OpaqueError {}
  47. const opaque = new OpaqueError()
  48. Object.defineProperty(opaque, "secret", { value: "hidden", enumerable: false })
  49. expect(errorFormat(opaque)).not.toBe("{}")
  50. expect(errorFormat(opaque)).toContain("OpaqueError")
  51. })
  52. test("handles opaque throwables with custom toString", () => {
  53. const err = {
  54. toString() {
  55. return "ResolveMessage: Cannot resolve module"
  56. },
  57. }
  58. expect(errorMessage(err)).toBe("ResolveMessage: Cannot resolve module")
  59. const data = errorData(err)
  60. expect(data.message).toBe("ResolveMessage: Cannot resolve module")
  61. expect(String(data.formatted)).toContain("ResolveMessage")
  62. })
  63. })