@goable-io/sdk 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/errors.js CHANGED
@@ -7,6 +7,8 @@
7
7
  * (DNS, connection, abort/timeout, JSON parse).
8
8
  */
9
9
  export class GoableApiError extends Error {
10
+ // Typed `string` (not the literal) so subclasses like DriftActiveError can
11
+ // override it with their own name.
10
12
  name = "GoableApiError";
11
13
  /** HTTP status code. */
12
14
  status;
@@ -16,6 +18,12 @@ export class GoableApiError extends Error {
16
18
  issues;
17
19
  /** Free-form extra context (e.g. plan info, quote id). */
18
20
  detail;
21
+ /** Seconds to wait before retrying, from the `Retry-After` header. Set on a
22
+ * `429`; `null` when the header is absent or unparseable. Lets a caller
23
+ * implement a compliant back-off (`if (err.status === 429) sleep(err.retryAfterSeconds)`). */
24
+ retryAfterSeconds;
25
+ /** Rate-limit snapshot from `X-RateLimit-*` headers, when the response carried them. */
26
+ rateLimit;
19
27
  constructor(status, code, message, extra) {
20
28
  super(message ?? code);
21
29
  this.status = status;
@@ -24,10 +32,32 @@ export class GoableApiError extends Error {
24
32
  this.issues = extra.issues;
25
33
  if (extra?.detail)
26
34
  this.detail = extra.detail;
35
+ this.retryAfterSeconds = extra?.retryAfterSeconds ?? null;
36
+ if (extra?.rateLimit)
37
+ this.rateLimit = extra.rateLimit;
27
38
  // Restore prototype chain for `instanceof` across transpilation targets.
28
39
  Object.setPrototypeOf(this, GoableApiError.prototype);
29
40
  }
30
41
  }
42
+ /**
43
+ * Raised on a `422 DRIFT_ACTIVE` from `POST /v1/underwriting/policy/bind`:
44
+ * the resolved cell has an open warning/critical L9 drift event, so the bind
45
+ * is refused (a watch-level event is a soft `driftAdvisories` on success, not
46
+ * an error). Subclasses `GoableApiError`, so existing `instanceof
47
+ * GoableApiError` / `.code === "DRIFT_ACTIVE"` checks keep working.
48
+ */
49
+ export class DriftActiveError extends GoableApiError {
50
+ name = "DriftActiveError";
51
+ /** The blocking cells, from the server's `detail.openDriftEvents`. Shape is
52
+ * per-cell and best-effort (documented, not part of the typed contract). */
53
+ openDriftEvents;
54
+ constructor(status, code, message, extra) {
55
+ super(status, code, message, extra);
56
+ const raw = extra?.detail?.openDriftEvents;
57
+ this.openDriftEvents = Array.isArray(raw) ? raw : [];
58
+ Object.setPrototypeOf(this, DriftActiveError.prototype);
59
+ }
60
+ }
31
61
  export class GoableNetworkError extends Error {
32
62
  name = "GoableNetworkError";
33
63
  /** "timeout" when the request was aborted by the configured timeout. */
@@ -41,9 +71,19 @@ export class GoableNetworkError extends Error {
41
71
  Object.setPrototypeOf(this, GoableNetworkError.prototype);
42
72
  }
43
73
  }
74
+ /** Parse an integer header, returning null when absent or non-numeric. */
75
+ function intHeader(headers, name) {
76
+ const v = headers?.get(name);
77
+ if (v == null)
78
+ return null;
79
+ const n = Number(v);
80
+ return Number.isFinite(n) ? n : null;
81
+ }
44
82
  /** Map a parsed error body + status into a GoableApiError. Tolerant of a
45
- * non-conforming body (falls back to the status code as the error code). */
46
- export function toApiError(status, body) {
83
+ * non-conforming body (falls back to the status code as the error code).
84
+ * When `headers` are supplied, surfaces `Retry-After` (as `retryAfterSeconds`)
85
+ * and the `X-RateLimit-*` snapshot on the resulting error. */
86
+ export function toApiError(status, body, headers) {
47
87
  const b = (body ?? {});
48
88
  const code = typeof b.error === "string" ? b.error : `HTTP_${status}`;
49
89
  const message = typeof b.message === "string" ? b.message : undefined;
@@ -52,6 +92,17 @@ export function toApiError(status, body) {
52
92
  extra.issues = b.issues;
53
93
  if (b.detail && typeof b.detail === "object")
54
94
  extra.detail = b.detail;
95
+ extra.retryAfterSeconds = intHeader(headers, "Retry-After");
96
+ const limit = intHeader(headers, "X-RateLimit-Limit");
97
+ const remaining = intHeader(headers, "X-RateLimit-Remaining");
98
+ const reset = intHeader(headers, "X-RateLimit-Reset");
99
+ if (limit !== null && remaining !== null && reset !== null) {
100
+ extra.rateLimit = { limit, remaining, reset };
101
+ }
102
+ // Specialise the one error the SDK models with its own class. Stays a
103
+ // GoableApiError subclass, so generic catch sites are unaffected.
104
+ if (code === "DRIFT_ACTIVE")
105
+ return new DriftActiveError(status, code, message, extra);
55
106
  return new GoableApiError(status, code, message, extra);
56
107
  }
57
108
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,MAAM,OAAO,cAAe,SAAQ,KAAK;IACrB,IAAI,GAAG,gBAAgB,CAAA;IACzC,wBAAwB;IACf,MAAM,CAAQ;IACvB,8EAA8E;IACrE,IAAI,CAAQ;IACrB,wEAAwE;IAC/D,MAAM,CAAiB;IAChC,0DAA0D;IACjD,MAAM,CAA0B;IAEzC,YACE,MAAc,EACd,IAAY,EACZ,OAAgB,EAChB,KAAqE;QAErE,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAA;QACtB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,KAAK,EAAE,MAAM;YAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;QAC7C,IAAI,KAAK,EAAE,MAAM;YAAE,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAA;QAC7C,yEAAyE;QACzE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,cAAc,CAAC,SAAS,CAAC,CAAA;IACvD,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IACzB,IAAI,GAAG,oBAAoB,CAAA;IAC7C,wEAAwE;IAC/D,IAAI,CAAiC;IAC5B,KAAK,CAAU;IAEjC,YAAY,OAAe,EAAE,IAAqC,EAAE,KAAe;QACjF,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;QAC3C,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,kBAAkB,CAAC,SAAS,CAAC,CAAA;IAC3D,CAAC;CACF;AASD;6EAC6E;AAC7E,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,IAAa;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAiB,CAAA;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,MAAM,EAAE,CAAA;IACrE,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAA;IACrE,MAAM,KAAK,GAAkE,EAAE,CAAA;IAC/E,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,MAAwB,CAAA;IACtE,IAAI,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ;QAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,MAAiC,CAAA;IAChG,OAAO,IAAI,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAA;AACzD,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}