Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrap error structure #1431

Merged
merged 45 commits into from
Jan 5, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
270612f
added tests for invoke error structure
krisbitney Nov 14, 2022
be51143
added InvokeError and error structure tests
krisbitney Nov 15, 2022
3dd3d17
uncommented some lines in error-structure.spec.ts
krisbitney Nov 15, 2022
d5f8b85
moved InvokeError to core-js
krisbitney Nov 15, 2022
f4993e4
custom error structure prints correct output
krisbitney Nov 18, 2022
b8399cf
added test for incompatible wasm wrapper version
krisbitney Nov 21, 2022
add1436
removed unnecessary files from deprecated wrapper test case
krisbitney Nov 21, 2022
b5db3f2
added more info to comment in WrapError.ts
krisbitney Nov 21, 2022
f04efd5
Merge remote-tracking branch 'origin/origin-dev' into wrap-error-stru…
krisbitney Dec 5, 2022
908fa7b
moved wrap error structure updates to core client
krisbitney Dec 6, 2022
97d4ceb
improved tests for wrap error structure
krisbitney Dec 7, 2022
4fa295d
added WrapError to more modules, added more error codes, improved tes…
krisbitney Dec 7, 2022
b314981
Merge remote-tracking branch 'origin/wrap-error-structure' into wrap-…
krisbitney Dec 7, 2022
beeb967
fixed WrapError parsing for multi-error stacks
krisbitney Dec 8, 2022
9db1636
initial wrap error structure tests passing
krisbitney Dec 8, 2022
a201bd6
added try-catch block to PluginModule method invocation
krisbitney Dec 9, 2022
ba5c3dc
fixed some plugin and client tests for WrapError
krisbitney Dec 9, 2022
bf7fb2a
fixed more plugin and client tests for WrapError
krisbitney Dec 9, 2022
743f239
added WASM_STATE_ERROR and WASM_SERIALIZATION_ERROR error codes to Wr…
krisbitney Dec 10, 2022
5566b13
removed unnecessary number specified on WASM_SUBINVOKE_ABORTED
krisbitney Dec 10, 2022
06d4164
removed CLIENT_QUERY... error codes; removed test:errors script from …
krisbitney Dec 17, 2022
b87ec3f
removed WASM_SERIALIZATION_ERROR code
krisbitney Dec 19, 2022
e12e539
removed leftover adjustments to error-structure.spec.ts made for testing
krisbitney Dec 19, 2022
5aeb31f
moved WrapError parsing to wasm-js package; combined wasm and plugin …
krisbitney Dec 20, 2022
7998b2a
moved WrapError parsing back to WrapError; re-added UNKNOWN error cod…
krisbitney Dec 21, 2022
d0d002b
Merge remote-tracking branch 'origin/origin-dev' into wrap-error-stru…
krisbitney Dec 21, 2022
045697d
Merge remote-tracking branch 'origin/origin-dev' into wrap-error-stru…
krisbitney Dec 22, 2022
a358818
changed URI_RESOLVER and URI_RESOLUTION error code names to URI_RESOL…
krisbitney Dec 22, 2022
9eb9c68
fixed error code name in WrapError
krisbitney Dec 22, 2022
03f6e59
lint
krisbitney Dec 28, 2022
c5c0d91
removed "metaMessage" concept from WrapError
krisbitney Dec 29, 2022
b551edb
added call to captureStackTrace in WrapError constructor
krisbitney Dec 29, 2022
4981dde
added error source to WrapErrors that are thrown from plugin wrappers…
krisbitney Dec 29, 2022
65e08b4
removed comments from testing
krisbitney Dec 29, 2022
84a33c1
fixed error strings in sanity.spec.ts in client
krisbitney Dec 29, 2022
d99fa44
added ".polywrap" to modulePathIgnorePatterns in jest config in client
krisbitney Dec 29, 2022
a309411
fixed some paths in wrap error tests
krisbitney Dec 29, 2022
4f0c681
removed unnecessary \r\n from WrapError regex
krisbitney Dec 29, 2022
1cde74f
adjusted patterns in WrapError regex that were marked "suspicious" by…
krisbitney Dec 29, 2022
bfab74f
wrap error codes now start at 1; abort in wasm-js no longer has a def…
krisbitney Jan 4, 2023
ad89070
split `abort` into two methods, one for aborted invocations and one f…
krisbitney Jan 5, 2023
1a1b1cf
fixed wrap error tests for name change of prop from "prev" to "innerE…
krisbitney Jan 5, 2023
dd2922f
Merge branch 'origin-dev' into wrap-error-structure
dOrgJelli Jan 5, 2023
4923540
fix: error test
dOrgJelli Jan 5, 2023
5995310
fix: error-structure tests
dOrgJelli Jan 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/js/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"test": "jest --passWithNoTests --runInBand --verbose=true --detectOpenHandles --forceExit",
"test:ci": "jest --passWithNoTests --runInBand --verbose --detectOpenHandles --forceExit",
"test:rust": "jest --passWithNoTests --runInBand --verbose --detectOpenHandles --forceExit --config ./jest.rs.config.js",
"test:watch": "jest --watch --passWithNoTests --verbose --detectOpenHandles"
"test:watch": "jest --watch --passWithNoTests --verbose --detectOpenHandles",
"test:errors": "yarn test src/__tests__/core/error-structure.spec.ts"
krisbitney marked this conversation as resolved.
Show resolved Hide resolved
},
"dependencies": {
"@polywrap/wrap-manifest-types-js": "0.10.0-pre.5",
Expand Down
231 changes: 231 additions & 0 deletions packages/js/client/src/__tests__/core/error-structure.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
import { GetPathToTestWrappers } from "@polywrap/test-cases";
import { Uri, PolywrapClient } from "../..";
import { buildWrapper } from "@polywrap/test-env-js";
import { WrapError, WrapErrorCode } from "@polywrap/core-js";

jest.setTimeout(660000);


// AS
const simpleWrapperPath = `${GetPathToTestWrappers()}/wasm-as/simple`;
const simpleWrapperUri = new Uri(`fs/${simpleWrapperPath}/build`);

const subinvokeErrorWrapperPath = `${GetPathToTestWrappers()}/wasm-as/subinvoke-error/invoke`;
const subinvokeErrorWrapperUri = new Uri(`fs/${subinvokeErrorWrapperPath}/build`);

const badMathWrapperPath = `${GetPathToTestWrappers()}/wasm-as/subinvoke-error/0-subinvoke`;
const badMathWrapperUri = new Uri(`fs/${badMathWrapperPath}/build`);

const badUtilWrapperPath = `${GetPathToTestWrappers()}/wasm-as/subinvoke-error/1-subinvoke`;
const badUtilWrapperUri = new Uri(`fs/${badUtilWrapperPath}/build`);

const incompatibleWrapperPath = `${GetPathToTestWrappers()}/wasm-as/simple-deprecated`;
const incompatibleWrapperUri = new Uri(`fs/${incompatibleWrapperPath}`);

// RS
const invalidTypesWrapperPath = `${GetPathToTestWrappers()}/wasm-rs/invalid-types`;
const invalidTypesWrapperUri = new Uri(`fs/${invalidTypesWrapperPath}/build`);

describe("error structure", () => {

let client: PolywrapClient;

beforeAll(async () => {
await buildWrapper(simpleWrapperPath);
await buildWrapper(badUtilWrapperPath);
await buildWrapper(badMathWrapperPath);
await buildWrapper(subinvokeErrorWrapperPath);
await buildWrapper(invalidTypesWrapperPath);

client = new PolywrapClient({
redirects: [
{
from: "ens/bad-math.eth",
to: badMathWrapperUri,
},
{
from: "ens/bad-util.eth",
to: badUtilWrapperUri,
}
]
})
});

test("Invoke a wrapper that is not found", async () => {
const result = await client.invoke<string>({
uri: simpleWrapperUri.uri + "-not-found",
method: "simpleMethod",
args: {
arg: "test",
},
});

expect(result.ok).toBeFalsy();
if (result.ok) throw Error("should never happen");

expect(result.error?.name).toEqual("UriResolutionError");
expect(result.error?.code).toEqual(WrapErrorCode.URI_NOT_FOUND);
expect(result.error?.reason.startsWith("Unable to find URI ")).toBeTruthy();
expect(result.error?.uri.endsWith("packages/test-cases/cases/wrappers/wasm-as/simple/build-not-found")).toBeTruthy();
expect(result.error?.resolutionStack).toBeTruthy();
});

test("Invoke a wrapper with malformed arguments - as", async () => {
const result = await client.invoke<string>({
uri: simpleWrapperUri.uri,
method: "simpleMethod",
args: {
arg: 3,
},
});

expect(result.ok).toBeFalsy();
if (result.ok) throw Error("should never happen");

expect(result.error?.name).toEqual("InvokeError");
expect(result.error?.code).toEqual(WrapErrorCode.WASM_SERIALIZATION_ERROR);
expect(result.error?.reason.startsWith("__wrap_abort:")).toBeTruthy();
expect(result.error?.uri.endsWith("packages/test-cases/cases/wrappers/wasm-as/simple/build")).toBeTruthy();
expect(result.error?.method).toEqual("simpleMethod");
expect(result.error?.args).toEqual("{\n \"arg\": 3\n}");
expect(result.error?.source).toEqual({ file: "~lib/@polywrap/wasm-as/msgpack/ReadDecoder.ts", row: 167, col: 5 });
});

test("Invoke a wrapper with malformed arguments - rs", async () => {
const result = await client.invoke<string>({
uri: invalidTypesWrapperUri.uri,
method: "boolMethod",
args: {
arg: 3,
},
});

expect(result.ok).toBeFalsy();
if (result.ok) throw Error("should never happen");

expect(result.error?.name).toEqual("InvokeError");
expect(result.error?.code).toEqual(WrapErrorCode.WASM_SERIALIZATION_ERROR);
expect(result.error?.reason.startsWith("__wrap_abort:")).toBeTruthy();
expect(result.error?.uri.endsWith("packages/test-cases/cases/wrappers/wasm-rs/invalid-types/build")).toBeTruthy();
expect(result.error?.method).toEqual("boolMethod");
expect(result.error?.args).toEqual("{\n \"arg\": 3\n}");
expect(result.error?.source).toEqual({ file: "src/wrap/module/wrapped.rs", row: 38, col: 13 });
});


test("Invoke a wrapper method that doesn't exist", async () => {
const result = await client.invoke<string>({
uri: simpleWrapperUri.uri,
method: "complexMethod",
args: {
arg: "test",
},
});

expect(result.ok).toBeFalsy();
if (result.ok) throw Error("should never happen");

expect(result.error?.name).toEqual("InvokeError");
expect(result.error?.code).toEqual(WrapErrorCode.WASM_INVOKE_FAIL);
expect(result.error?.reason.startsWith("Could not find invoke function")).toBeTruthy();
expect(result.error?.uri.endsWith("packages/test-cases/cases/wrappers/wasm-as/simple/build")).toBeTruthy();
expect(result.error?.method).toEqual("complexMethod");
expect(result.error?.args).toEqual("{\n \"arg\": \"test\"\n}");
expect(result.error?.toString().split("52").length).toEqual(2);
expect(result.error?.prev).toBeUndefined();
});

test("Subinvoke a wrapper that is not found", async () => {
const result = await client.invoke<number>({
uri: subinvokeErrorWrapperUri.uri,
method: "subWrapperNotFound",
args: {
a: 1,
b: 1,
},
});

expect(result.ok).toBeFalsy();
if (result.ok) throw Error("should never happen");

expect(result.error?.name).toEqual("InvokeError");
expect(result.error?.code).toEqual(WrapErrorCode.WASM_INVOKE_ABORTED);
expect(result.error?.reason.startsWith("SubInvocation exception encountered")).toBeTruthy();
expect(result.error?.uri.endsWith("packages/test-cases/cases/wrappers/wasm-as/subinvoke-error/invoke/build")).toBeTruthy();
expect(result.error?.method).toEqual("subWrapperNotFound");
expect(result.error?.args).toEqual("{\n \"a\": 1,\n \"b\": 1\n}");
expect(result.error?.source).toEqual({ file: "~lib/@polywrap/wasm-as/containers/Result.ts", row: 171, col: 13 });

expect(result.error?.prev instanceof WrapError).toBeTruthy();
const prev = result.error?.prev as WrapError;
expect(prev.name).toEqual("UriResolutionError");
expect(prev.code).toEqual(WrapErrorCode.URI_NOT_FOUND);
expect(prev.reason).toEqual("Unable to find URI wrap://ens/not-found.eth.");
expect(prev.uri).toEqual("wrap://ens/not-found.eth");
expect(prev.resolutionStack).toBeTruthy();
});

test("Subinvoke error two layers deep", async () => {
const result = await client.invoke<number>({
uri: subinvokeErrorWrapperUri.uri,
method: "throwsInTwoSubinvokeLayers",
args: {
a: 1,
b: 1,
},
});

expect(result.ok).toBeFalsy();
if (result.ok) throw Error("should never happen");

expect(result.error?.name).toEqual("InvokeError");
expect(result.error?.code).toEqual(WrapErrorCode.WASM_INVOKE_ABORTED);
expect(result.error?.reason.startsWith("SubInvocation exception encountered")).toBeTruthy();
expect(result.error?.uri.endsWith("packages/test-cases/cases/wrappers/wasm-as/subinvoke-error/invoke/build")).toBeTruthy();
expect(result.error?.method).toEqual("throwsInTwoSubinvokeLayers");
expect(result.error?.args).toEqual(`{
"a": 1,
"b": 1
}`);
expect(result.error?.source).toEqual({ file: "~lib/@polywrap/wasm-as/containers/Result.ts", row: 171, col: 13 });

expect(result.error?.prev instanceof WrapError).toBeTruthy();
const prev = result.error?.prev as WrapError;
expect(prev.name).toEqual("InvokeError");
expect(prev.code).toEqual(WrapErrorCode.WASM_INVOKE_ABORTED);
expect(prev.reason.startsWith("SubInvocation exception encountered")).toBeTruthy();
expect(prev.uri).toEqual("wrap://ens/bad-math.eth");
expect(prev.method).toEqual("subInvokeWillThrow");
expect(prev.args).toEqual("{\n \"0\": 130,\n \"1\": 161,\n \"2\": 97,\n \"3\": 1,\n \"4\": 161,\n \"5\": 98,\n \"6\": 1\n}");
expect(prev.source).toEqual({ file: "~lib/@polywrap/wasm-as/containers/Result.ts", row: 171, col: 13 });

expect(prev.prev instanceof WrapError).toBeTruthy();
const prevOfPrev = prev.prev as WrapError;
expect(prevOfPrev.name).toEqual("InvokeError");
expect(prevOfPrev.code).toEqual(WrapErrorCode.WASM_INVOKE_ABORTED);
expect(prevOfPrev.reason).toEqual("__wrap_abort: I threw an error!");
expect(prevOfPrev.uri.endsWith("wrap://ens/bad-util.eth")).toBeTruthy();
expect(prevOfPrev.method).toEqual("iThrow");
expect(prevOfPrev.args).toEqual("{\n \"0\": 129,\n \"1\": 161,\n \"2\": 97,\n \"3\": 0\n}");
expect(prevOfPrev.source).toEqual({ file: "src/index.ts", row: 5, col: 5 });
});

test("Invoke a wrapper of incompatible version", async () => {
const result = await client.invoke<string>({
uri: incompatibleWrapperUri.uri,
method: "simpleMethod",
args: {
arg: "test",
},
});

expect(result.ok).toBeFalsy();
if (result.ok) throw Error("should never happen");

expect(result.error?.name).toEqual("UriResolutionError");
expect(result.error?.code).toEqual(WrapErrorCode.URI_RESOLVER);
expect(result.error?.uri.endsWith("packages/test-cases/cases/wrappers/wasm-as/simple-deprecated")).toBeTruthy();
expect(result.error?.resolutionStack).toBeDefined();
expect(`${result.error?.cause}`).toContain(`Unrecognized WrapManifest schema version "0.0.1"`);
});
});
4 changes: 2 additions & 2 deletions packages/js/client/src/__tests__/core/sanity.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ describe("sanity", () => {
expect(result.ok).toBeFalsy();
let resultError = (result as { error: Error }).error;
expect(resultError).toBeTruthy();
expect(resultError.message).toContain("Error resolving URI");
expect(resultError.message).toContain("Unable to resolve URI");

let fooPackage: IUriPackage<string> = {
uri: fooUri,
Expand All @@ -95,7 +95,7 @@ describe("sanity", () => {
resultError = (result as { error: Error }).error;
expect(result.ok).toBeFalsy();
expect(resultError).toBeTruthy();
expect(resultError.message).toContain("Error resolving URI");
expect(resultError.message).toContain("URI not found");

await buildWrapper(greetingPath);

Expand Down
2 changes: 1 addition & 1 deletion packages/js/client/src/__tests__/e2e/test-cases.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ export const runInvalidTypesTest = async (client: CoreClient, uri: string) => {
arg: 10,
},
});
invalidBoolIntSent = invalidBoolIntSent as { ok: false; error: Error };
invalidBoolIntSent = invalidBoolIntSent as ErrResult;
expect(invalidBoolIntSent.error).toBeTruthy();
expect(invalidBoolIntSent.error?.message).toMatch(
/Property must be of type 'bool'. Found 'int'./
Expand Down
Loading