Like @Iker mentioned batch_all
sends a batch of dispatch calls and atomically executes them. The whole transaction will rollback and fail if any of the calls fail.
This video on the utility pallet may be helpful:
Here is an example for listening for system.ExtrinsicFailed
as noted here:
const txs = [
api.tx.balances.transfer(EVE, 5000000),
// api.tx.balances.setBalance(EVE, 100000000, 0),
api.tx.identity.clearIdentity(),
api.tx.system.remark('hello world'.repeat(10)),
]
await api.tx.utility.batchAll(txs).signAndSend(alice, ({ status, events }) => {
if (status.isInBlock || status.isFinalized) {
events
// find/filter for failed events
.filter(({ event }) =>
api.events.system.ExtrinsicFailed.is(event)
)
// we know that data for system.ExtrinsicFailed is
// (DispatchError, DispatchInfo)
.forEach(({ event: { data: [error, info] } }) => {
if (error.isModule) {
// for module errors, we have the section indexed, lookup
const decoded = api.registry.findMetaError(error.asModule);
const { docs, method, section } = decoded;
console.log(`${section}.${method}: ${docs.join(' ')}`);
} else {
// Other, CannotLookup, BadOrigin, no extra info
console.log(error.toString());
}
});
}
});
Output:
identity.NotNamed: Account isn't named.
If you are using sudo then you would listen for the Sudid
event as noted here:
const txs = [
api.tx.balances.forceTransfer(ALICE, BOB, 100),
// api.tx.balances.transfer(EVE, 5000000),
api.tx.balances.setBalance(BOB, 1000, 0),
api.tx.balances.forceTransfer(BOB, EVE, 10000),
api.tx.system.remark('hello world'.repeat(10)),
]
const unsub = await api.tx.sudo.sudo(api.tx.utility.batchAll(txs)).signAndSend(alice, ({ status, events }) => {
if (status.isInBlock || status.isFinalized) {
events
// We know this tx should result in `Sudid` event.
.filter(({ event }) =>
api.events.sudo.Sudid.is(event)
)
// We know that `Sudid` returns just a `Result`
.forEach(({ event : { data: [result] } }) => {
// Now we look to see if the extrinsic was actually successful or not...
if (result.isError) {
let error = result.asError;
if (error.isModule) {
// for module errors, we have the section indexed, lookup
const decoded = api.registry.findMetaError(error.asModule);
const { docs, name, section } = decoded;
console.log(`${section}.${name}: ${docs.join(' ')}`);
} else {
// Other, CannotLookup, BadOrigin, no extra info
console.log(error.toString());
}
}
});
unsub();
}
});
Output:
balances.InsufficientBalance: Balance too low to send value