diff --git a/package-lock.json b/package-lock.json index d62c3af..0e592c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@codex-storage/sdk-js", - "version": "0.0.5", + "version": "0.0.^", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@codex-storage/sdk-js", - "version": "0.0.5", + "version": "0.0.^", "license": "MIT", "dependencies": { "valibot": "^0.32.0" diff --git a/package.json b/package.json index 4235492..2f79c9e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@codex-storage/sdk-js", - "version": "0.0.5", + "version": "0.0.^", "description": "Codex SDK to interact with the Codex decentralized storage network.", "repository": { "type": "git", diff --git a/src/data/data.ts b/src/data/data.ts index 7c71fe3..113c11d 100644 --- a/src/data/data.ts +++ b/src/data/data.ts @@ -1,4 +1,5 @@ import { Api } from "../api/config"; +import { CodexError } from "../errors/errors"; import { Fetch } from "../fetch-safe/fetch-safe"; import type { SafeValue } from "../values/values"; import type { @@ -77,10 +78,9 @@ export class CodexData { if (xhr.status != 200) { resolve({ error: true, - data: { + data: new CodexError(xhr.responseText, { code: xhr.status, - message: xhr.responseText, - }, + }), }); } else { resolve({ error: false, data: xhr.response }); @@ -90,9 +90,7 @@ export class CodexData { xhr.onerror = function () { resolve({ error: true, - data: { - message: "Something went wrong during the file upload.", - }, + data: new CodexError("Something went wrong during the file upload."), }); }; }); diff --git a/src/debug/debug.test.ts b/src/debug/debug.test.ts index ec14479..e298bc9 100644 --- a/src/debug/debug.test.ts +++ b/src/debug/debug.test.ts @@ -1,6 +1,7 @@ import { afterEach, assert, describe, it, vi } from "vitest"; import { CodexDebug } from "./debug"; import type { CodexLogLevel } from "./types"; +import { CodexError } from "../errors/errors"; describe("debug", () => { afterEach(() => { @@ -14,8 +15,7 @@ describe("debug", () => { assert.deepStrictEqual(response, { error: true, - data: { - message: "Cannot validate the input", + data: new CodexError("Cannot validate the input", { errors: [ { expected: @@ -26,7 +26,7 @@ describe("debug", () => { received: '"TEST"', }, ], - }, + }), }); }); diff --git a/src/debug/debug.ts b/src/debug/debug.ts index 1334dd7..fa9cfa6 100644 --- a/src/debug/debug.ts +++ b/src/debug/debug.ts @@ -1,5 +1,5 @@ import { Api } from "../api/config"; -import { CodexValibotIssuesMap } from "../errors/errors"; +import { CodexError, CodexValibotIssuesMap } from "../errors/errors"; import { Fetch } from "../fetch-safe/fetch-safe"; import type { SafeValue } from "../values/values"; import { CodexLogLevel, type CodexDebugInfo } from "./types"; @@ -21,10 +21,9 @@ export class CodexDebug { if (!result.success) { return Promise.resolve({ error: true, - data: { - message: "Cannot validate the input", + data: new CodexError("Cannot validate the input", { errors: CodexValibotIssuesMap(result.issues), - }, + }), }); } diff --git a/src/errors/errors.ts b/src/errors/errors.ts index b678876..c211a89 100644 --- a/src/errors/errors.ts +++ b/src/errors/errors.ts @@ -13,11 +13,27 @@ type ValidationError = { * `errors`: A {ValidationError} array when it comes from an object validation process * `stack`: The error stack when the CodexError results from a error thrown */ -export type CodexError = { - message: string; - code?: number; - errors?: ValidationError[]; - stack?: string; +export class CodexError extends Error { + code: number | null; + errors: ValidationError[] | null; + sourceStack: string | null; + + constructor( + message: string, + { code, errors, sourceStack }: CodexErrorProps = {} + ) { + super(message); + + this.code = code || null; + this.errors = errors || null; + this.sourceStack = sourceStack || null; + } +} + +type CodexErrorProps = { + code?: number | null; + errors?: ValidationError[] | null; + sourceStack?: string | null; }; export const CodexValibotIssuesMap = (issues: InferIssue[]) => diff --git a/src/fetch-safe/fetch-safe.test.ts b/src/fetch-safe/fetch-safe.test.ts index 79bf43f..0464cba 100644 --- a/src/fetch-safe/fetch-safe.test.ts +++ b/src/fetch-safe/fetch-safe.test.ts @@ -1,5 +1,6 @@ import { afterEach, assert, describe, it, vi } from "vitest"; import { Fetch } from "../fetch-safe/fetch-safe"; +import { CodexError } from "../async"; describe.only("fetch", () => { afterEach(() => { @@ -18,10 +19,9 @@ describe.only("fetch", () => { method: "GET", }); - const error = { - message: "error", + const error = new CodexError("error", { code: 500, - }; + }); assert.deepStrictEqual(result, { error: true, data: error }); }); diff --git a/src/fetch-safe/fetch-safe.ts b/src/fetch-safe/fetch-safe.ts index dcc2fa4..3aa31d4 100644 --- a/src/fetch-safe/fetch-safe.ts +++ b/src/fetch-safe/fetch-safe.ts @@ -1,3 +1,4 @@ +import { CodexError } from "../errors/errors"; import { Promises } from "../promise-safe/promise-safe"; import { type SafeValue } from "../values/values"; @@ -8,15 +9,14 @@ export const Fetch = { if (res.error) { return { error: true, - data: { - message: res.data.message, + data: new CodexError(res.data.message, { code: 502, - }, + }), }; } if (!res.data.ok) { - const message = await Promises.safe(() => res.data.text()); + const message = await Promises.safe(res.data.text); if (message.error) { return message; @@ -24,10 +24,9 @@ export const Fetch = { return { error: true, - data: { - message: message.data, + data: new CodexError(message.data, { code: res.data.status, - }, + }), }; } diff --git a/src/marketplace/marketplace.test.ts b/src/marketplace/marketplace.test.ts index 3e08896..ebdaea6 100644 --- a/src/marketplace/marketplace.test.ts +++ b/src/marketplace/marketplace.test.ts @@ -6,6 +6,7 @@ import { randomInt, randomString, } from "../tests/tests.util"; +import { CodexError } from "../errors/errors"; function createStorageRequest() { return { @@ -23,8 +24,7 @@ function createStorageRequest() { function missingNumberValidationError(field: string) { return { error: true as any, - data: { - message: "Cannot validate the input", + data: new CodexError("Cannot validate the input", { errors: [ { path: field, @@ -33,15 +33,14 @@ function missingNumberValidationError(field: string) { received: "undefined", }, ], - }, + }), }; } function extraValidationError(field: string, value: unknown) { return { error: true as any, - data: { - message: "Cannot validate the input", + data: new CodexError("Cannot validate the input", { errors: [ { path: field, @@ -50,15 +49,14 @@ function extraValidationError(field: string, value: unknown) { received: `"${value}"`, }, ], - }, + }), }; } function missingStringValidationError(field: string) { return { error: true as any, - data: { - message: "Cannot validate the input", + data: new CodexError("Cannot validate the input", { errors: [ { path: field, @@ -67,15 +65,14 @@ function missingStringValidationError(field: string) { received: "undefined", }, ], - }, + }), }; } function mistypeNumberValidationError(field: string, value: string) { return { error: true as any, - data: { - message: "Cannot validate the input", + data: new CodexError("Cannot validate the input", { errors: [ { path: field, @@ -84,15 +81,14 @@ function mistypeNumberValidationError(field: string, value: string) { received: `"${value}"`, }, ], - }, + }), }; } function minNumberValidationError(field: string, min: number) { return { error: true as any, - data: { - message: "Cannot validate the input", + data: new CodexError("Cannot validate the input", { errors: [ { path: field, @@ -101,7 +97,7 @@ function minNumberValidationError(field: string, min: number) { received: "0", }, ], - }, + }), }; } diff --git a/src/marketplace/marketplace.ts b/src/marketplace/marketplace.ts index 496ae0f..72e957b 100644 --- a/src/marketplace/marketplace.ts +++ b/src/marketplace/marketplace.ts @@ -1,6 +1,6 @@ import * as v from "valibot"; import { Api } from "../api/config"; -import { CodexValibotIssuesMap } from "../errors/errors"; +import { CodexError, CodexValibotIssuesMap } from "../errors/errors"; import { Fetch } from "../fetch-safe/fetch-safe"; import type { SafeValue } from "../values/values"; import { @@ -82,10 +82,9 @@ export class CodexMarketplace { if (!result.success) { return { error: true, - data: { - message: "Cannot validate the input", + data: new CodexError("Cannot validate the input", { errors: CodexValibotIssuesMap(result.issues), - }, + }), }; } @@ -116,10 +115,9 @@ export class CodexMarketplace { if (!result.success) { return { error: true, - data: { - message: "Cannot validate the input", + data: new CodexError("Cannot validate the input", { errors: CodexValibotIssuesMap(result.issues), - }, + }), }; } @@ -229,10 +227,9 @@ export class CodexMarketplace { if (!result.success) { return { error: true, - data: { - message: "Cannot validate the input", + data: new CodexError("Cannot validate the input", { errors: CodexValibotIssuesMap(result.issues), - }, + }), }; } diff --git a/src/node/node.ts b/src/node/node.ts index 1029e8e..5b2eb6b 100644 --- a/src/node/node.ts +++ b/src/node/node.ts @@ -1,6 +1,6 @@ import { Api } from "../api/config"; -import type { SafeValue } from "../async"; import { Fetch } from "../fetch-safe/fetch-safe"; +import type { SafeValue } from "../values/values"; import type { CodexSpr } from "./types"; export class CodexNode { diff --git a/src/promise-safe/promise-safe.test.ts b/src/promise-safe/promise-safe.test.ts index 3ed6e79..bccbdc5 100644 --- a/src/promise-safe/promise-safe.test.ts +++ b/src/promise-safe/promise-safe.test.ts @@ -1,5 +1,6 @@ import { assert, describe, it } from "vitest"; import { Promises } from "./promise-safe"; +import { CodexError } from "../async"; describe("promise safe", () => { it("returns an error when the promise failed", async () => { @@ -7,7 +8,10 @@ describe("promise safe", () => { () => new Promise((_, reject) => reject("error")) ); - assert.deepStrictEqual(result, { error: true, data: { message: "error" } }); + assert.deepStrictEqual(result, { + error: true, + data: new CodexError("error"), + }); }); it("returns the value when the promise succeed", async () => { diff --git a/src/promise-safe/promise-safe.ts b/src/promise-safe/promise-safe.ts index 95065c5..0a9cb91 100644 --- a/src/promise-safe/promise-safe.ts +++ b/src/promise-safe/promise-safe.ts @@ -1,3 +1,4 @@ +import { CodexError } from "../async"; import type { SafeValue } from "../values/values"; export const Promises = { @@ -7,14 +8,11 @@ export const Promises = { return { error: false, data: result }; } catch (e) { - const opts = e instanceof Error && e.stack ? { stack: e.stack } : {}; - return { error: true, - data: { - message: e instanceof Error ? e.message : "" + e, - ...opts, - }, + data: new CodexError(e instanceof Error ? e.message : "" + e, { + sourceStack: e instanceof Error ? e.stack || null : null, + }), }; } },