Skip to content

Commit 320ee58

Browse files
authored
Fix handling ScError types in scValToNative (#753)
* Add a unit test to match
1 parent 442a3b5 commit 320ee58

File tree

3 files changed

+44
-15
lines changed

3 files changed

+44
-15
lines changed

CHANGELOG.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,19 @@
22

33
## Unreleased
44

5+
### Fixed
6+
* `scValToNative` would fail when the values contained error codes because the parsing routine hadn't been updated to the new error schemas. Errors are now converted to the following format:
7+
8+
```typescript
9+
interface Error {
10+
type: "contract" | "soroban";
11+
code: number;
12+
value?: string; // only present for type === 'soroban'
13+
}
14+
```
15+
16+
You can refer to the [XDR documentation](https://github.com/stellar/stellar-xdr/blob/70180d5e8d9caee9e8645ed8a38c36a8cf403cd9/Stellar-contract.x#L76-L115) for additional explanations for each error code.
17+
518

619
## [`v12.0.0`](https://github.com/stellar/js-stellar-base/compare/v11.0.1...v12.0.0)
720

src/scval.js

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -351,21 +351,19 @@ export function scValToNative(scv) {
351351
case xdr.ScValType.scvDuration().value:
352352
return new xdr.Uint64(scv.value()).toBigInt();
353353

354-
case xdr.ScValType.scvStatus().value:
355-
// TODO: Convert each status type into a human-readable error string?
356-
switch (scv.value().switch()) {
357-
case xdr.ScStatusType.sstOk().value:
358-
case xdr.ScStatusType.sstUnknownError().value:
359-
case xdr.ScStatusType.sstHostValueError().value:
360-
case xdr.ScStatusType.sstHostObjectError().value:
361-
case xdr.ScStatusType.sstHostFunctionError().value:
362-
case xdr.ScStatusType.sstHostStorageError().value:
363-
case xdr.ScStatusType.sstHostContextError().value:
364-
case xdr.ScStatusType.sstVmError().value:
365-
case xdr.ScStatusType.sstContractError().value:
366-
case xdr.ScStatusType.sstHostAuthError().value:
367-
default:
368-
break;
354+
case xdr.ScValType.scvError().value:
355+
switch (scv.error().switch().value) {
356+
// Distinguish errors from the user contract.
357+
case xdr.ScErrorType.sceContract().value:
358+
return { type: 'contract', code: scv.error().contractCode() };
359+
default: {
360+
const err = scv.error();
361+
return {
362+
type: 'system',
363+
code: err.code().value,
364+
value: err.code().name
365+
};
366+
}
369367
}
370368

371369
// in the fallthrough case, just return the underlying value directly

test/unit/scval_test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,4 +237,22 @@ describe('parsing and building ScVals', function () {
237237
expect(scv).to.deep.equal(equiv);
238238
});
239239
});
240+
241+
it('parses errors', function () {
242+
const userErr = xdr.ScVal.scvError(xdr.ScError.sceContract(1234));
243+
const systemErr = xdr.ScVal.scvError(
244+
xdr.ScError.sceWasmVm(xdr.ScErrorCode.scecInvalidInput())
245+
);
246+
247+
const native = scValToNative(xdr.ScVal.scvVec([userErr, systemErr]));
248+
249+
expect(native).to.deep.equal([
250+
{ type: 'contract', code: 1234 },
251+
{
252+
type: 'system',
253+
code: systemErr.error().code().value,
254+
value: systemErr.error().code().name
255+
}
256+
]);
257+
});
240258
});

0 commit comments

Comments
 (0)