hyperledger / aries-askar

Secure storage designed for Hyperledger Aries agents.
Apache License 2.0
58 stars 44 forks source link

[JS] Set custom `stack` on error when using `promisifyWithResponse` #220

Open TimoGlastra opened 7 months ago

TimoGlastra commented 7 months ago

When calling methods over FFI with a callback the error stack shows e.g. this:

/Users/timo/Developer/Playground/askar-transaction-test/node_modules/.pnpm/@hyperledger+aries-askar-nodejs@0.2.0-dev.6/node_modules/@hyperledger/aries-askar-nodejs/build/NodeJSAriesAskar.js:90
        return new aries_askar_shared_1.AriesAskarError(error);
               ^

AriesAskarError: Backend error
Caused by: no rows returned by a query that expected to return at least one row
    at NodeJSAriesAskar.getAriesAskarError (/Users/timo/Developer/Playground/askar-transaction-test/node_modules/.pnpm/@hyperledger+aries-askar-nodejs@0.2.0-dev.6/node_modules/@hyperledger/aries-askar-nodejs/src/NodeJSAriesAskar.ts:219:12)
    at cb (/Users/timo/Developer/Playground/askar-transaction-test/node_modules/.pnpm/@hyperledger+aries-askar-nodejs@0.2.0-dev.6/node_modules/@hyperledger/aries-askar-nodejs/src/NodeJSAriesAskar.ts:169:30)
    at Object.<anonymous> (/Users/timo/Developer/Playground/askar-transaction-test/node_modules/.pnpm/@2060.io+ffi-napi@4.0.8/node_modules/@2060.io/ffi-napi/lib/callback.js:66:27) {
  code: 1
}

It's not very helpful as it shows the callback stacktrace, losing the original call.

If we create a new Error().stack at the top level of promisifyWithResponse (or promisify), and then pass this to the error handler and overwrite the stack of the error we get this:

node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^

AriesAskarError
    at NodeJSAriesAskar.NodeJSAriesAskar.promisifyWithResponse (/Users/timo/Developer/Playground/askar-transaction-test/node_modules/.pnpm/@hyperledger+aries-askar-nodejs@0.2.0-dev.6/node_modules/@hyperledger/aries-askar-nodejs/src/NodeJSAriesAskar.ts:164:16)
    at NodeJSAriesAskar.storeProvision (/Users/timo/Developer/Playground/askar-transaction-test/node_modules/.pnpm/@hyperledger+aries-askar-nodejs@0.2.0-dev.6/node_modules/@hyperledger/aries-askar-nodejs/src/NodeJSAriesAskar.ts:1038:4)
    at Function.provision (/Users/timo/Developer/Playground/askar-transaction-test/node_modules/.pnpm/@hyperledger+aries-askar-shared@0.2.0-dev.6/node_modules/@hyperledger/aries-askar-shared/src/store/Store.ts:68:37)
    at run (/Users/timo/Developer/Playground/askar-transaction-test/index.ts:8:29)
    at <anonymous> (/Users/timo/Developer/Playground/askar-transaction-test/index.ts:31:1)
    at Object.<anonymous> (/Users/timo/Developer/Playground/askar-transaction-test/index.ts:31:5)
    at Module._compile (node:internal/modules/cjs/loader:1356:14)
    at Object.S (/Users/timo/Developer/Playground/askar-transaction-test/node_modules/.pnpm/tsx@4.7.0/node_modules/tsx/dist/cjs/index.cjs:1:1292)
    at Module.load (node:internal/modules/cjs/loader:1197:32)
    at Module._load (node:internal/modules/cjs/loader:1013:12) {
  code: 1
}

Which now conatins the actual method that was called. It's still not the most pretty but seeint that NodeJSAriesAskar.storeProvision failed in /Users/timo/Developer/Playground/askar-transaction-test/index.ts:8:29 is really helpful

We can do this for all the wrappers. WDYT @genaris @berendsliedrecht?

berendsliedrecht commented 7 months ago

Looks good, yes!

I would still like to look at passing the backtrace of Rust along as well. Would be nice if we could create something custom that contains a jsStacktrace and a rustStacktrace or something like that.