Skip to content

Commit

Permalink
feat: panic receipts have doc links
Browse files Browse the repository at this point in the history
  • Loading branch information
QuinnLee committed Aug 22, 2022
1 parent d710e52 commit 4acd31b
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 5 deletions.
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';
14 changes: 10 additions & 4 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 All @@ -41,12 +44,15 @@ export class ScriptResultDecoderError extends Error {
.join('\n')}`
: null;
const receiptsText = `Receipts:\n${JSON.stringify(
result.receipts.map(({ type, ...r }) => ({ type: ReceiptType[type], ...r })),
result.receipts.map((receipt) => ({
...receipt,
type: ReceiptType[receipt.type],
})),
bigintReplacer,
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 { CallResult, 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 4acd31b

Please sign in to comment.