Skip to content

Commit

Permalink
feat: panic receipts have doc links (#456)
Browse files Browse the repository at this point in the history
  • Loading branch information
QuinnLee committed Aug 24, 2022
1 parent 745e65b commit 48285d4
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changeset/curvy-bears-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@fuel-ts/contract": minor
"@fuel-ts/script": minor
---

Failures now output the reason
39 changes: 39 additions & 0 deletions packages/script/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// From https://github.com/FuelLabs/fuel-asm/blob/eb78378c3b7c22a53b834381c387d89b3c0ef122/src/panic_reason.rs#L13
export const PANIC_REASONS = [
'Success',
'Revert',
'OutOfGas',
'TransactionValidity',
'MemoryOverflow',
'ArithmeticOverflow',
'ContractNotFound',
'MemoryOwnership',
'NotEnoughBalance',
'ExpectedInternalContext',
'AssetIdNotFound',
'InputNotFound',
'OutputNotFound',
'WitnessNotFound',
'TransactionMaturity',
'InvalidMetadataIdentifier',
'MalformedCallStructure',
'ReservedRegisterNotWritable',
'ErrorFlag',
'InvalidImmediateValue',
'ExpectedCoinInput',
'MaxMemoryAccess',
'MemoryWriteOverlap',
'ContractNotInInputs',
'InternalBalanceOverflow',
'ContractMaxSize',
'ExpectedUnallocatedStack',
'MaxStaticContractsReached',
'TransferAmountCannotBeZero',
'ExpectedOutputVariable',
'ExpectedParentInternalContext',
'IllegalJump',
'NonZeroMessageOutputRecipient',
'ZeroedMessageOutputRecipient',
];

export const PANIC_DOC_URL = 'https://docs.rs/fuel-asm/latest/fuel_asm/enum.PanicReason.html';
9 changes: 6 additions & 3 deletions packages/script/src/errors.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import { ZeroBytes32 } from '@fuel-ts/constants';
import type {
CallResult,
TransactionResult,
TransactionResultLogDataReceipt,
TransactionResultLogReceipt,
TransactionResultRevertReceipt,
} from '@fuel-ts/providers';
import { ReceiptType } from '@fuel-ts/transactions';

import { getDocs } from './utils';

const bigintReplacer = (key: unknown, value: unknown) =>
typeof value === 'bigint' ? value.toString() : value;

const printLineWithId = (id: string, line: string) =>
`${id === ZeroBytes32 ? 'script' : id}: ${line}`;

export class ScriptResultDecoderError extends Error {
constructor(result: CallResult, message: string) {
constructor(result: TransactionResult<'failure'>, message: string) {
const docLink = JSON.stringify(getDocs(result.status), null, 2);
const revertReceipts = result.receipts.filter(
(r) => r.type === ReceiptType.Revert
) as TransactionResultRevertReceipt[];
Expand Down Expand Up @@ -46,7 +49,7 @@ export class ScriptResultDecoderError extends Error {
2
)}`;
super(
`${message}\n\n${revertsText ? `${revertsText}\n\n` : ''}${
`${message}\n\n${docLink}\n\n${revertsText ? `${revertsText}\n\n` : ''}${
logsText ? `${logsText}\n\n` : ''
}${receiptsText}`
);
Expand Down
6 changes: 5 additions & 1 deletion packages/script/src/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
TransactionResultReturnDataReceipt,
TransactionResultRevertReceipt,
TransactionResultScriptResultReceipt,
TransactionResult,
} from '@fuel-ts/providers';
import { ReceiptType } from '@fuel-ts/transactions';

Expand Down Expand Up @@ -111,7 +112,10 @@ export class Script<TData = void, TResult = void> {
const decoded = this.scriptResultDecoder(scriptResult);
return decoded;
} catch (error) {
throw new ScriptResultDecoderError(callResult, (error as Error).message);
throw new ScriptResultDecoderError(
callResult as TransactionResult<'failure'>,
(error as Error).message
);
}
}
}
19 changes: 19 additions & 0 deletions packages/script/src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { TransactionResult } from '@fuel-ts/providers';

import { PANIC_DOC_URL, PANIC_REASONS } from './constants';

const getFailureReason = (reason: string): string =>
PANIC_REASONS.includes(reason) ? reason : 'unknown';

export const getDocs = (
status: TransactionResult<'failure'>['status']
): { doc: string; reason: string } => {
if (status?.type === 'failure') {
const reason = getFailureReason(status.reason);
return {
doc: reason !== 'unknown' ? `${PANIC_DOC_URL}#variant.${reason}` : PANIC_DOC_URL,
reason,
};
}
return { doc: PANIC_DOC_URL, reason: 'unknown' };
};

0 comments on commit 48285d4

Please sign in to comment.