Skip to main content

Errors

Errors that come from the node or the client extend IotaGrpcError. Invalid arguments are caught before anything is sent, and throw a plain TypeError or RangeError instead.

Error classes​

ErrorRaised whenFields
TransportErrorThe whole call failed: the node could not be reached, refused the request, or the call was cancelledcode (Connect Code), detail, cause (ConnectError)
ServerErrorThe node refused one item of a batch. It is returned in that item's slot, and thrown by the single-item methodscode (numeric gRPC code), detail
EmptyRequestErrorA batch method was called with an empty list
UnexpectedEndOfStreamErrorA response the node split into several messages ended before the last one
ProtoConversionErrorA field the client or a decoder needs is missing, usually because the read mask left it out, or holds bytes that do not decode
SignatureConversionErrorA signature passed to executeTransaction(s) is not a valid serialized signature
ProtocolErrorThe node's answer broke the API contract. Base of the classes below
TypeErrorAn address, object ID, digest, type tag, transaction or view argument is malformed. Not an IotaGrpcError
RangeErrormaxMessageSizeBytes or limit is out of range. Not an IotaGrpcError

ProtocolError has these subclasses:

ErrorRaised when
UnexpectedResultCountErrorA batch answer has a different number of results than items asked for
UnexpectedObjectErrorA slot of getObjects holds a different object than the one asked for there
UnexpectedTransactionErrorA slot of getTransactions or executeTransactions holds a different transaction
UnknownVariantErrorThe node sent a variant this version of the client does not know
EmptyResponseFieldErrorThe node left out a field it must always send
CheckpointStreamErrorA checkpoint arrived out of order or incomplete. Base of DataBeforeHeaderError, IncompleteCheckpointError, SequenceNumberMismatchError, UnknownPayloadError and IncompleteStreamError

A ProtocolError means the node or the client has a bug. Your code did nothing wrong, and the error is worth reporting.

Status codes​

TransportError.code and ServerError.code are gRPC status codes. Compare them against Connect's Code enum:

import { Code } from '@connectrpc/connect';
CodeTypical cause
NotFoundThe object or transaction does not exist, was deleted, or was pruned
FailedPreconditionObjects or changes were asked for on a transaction whose objects the node has pruned
InvalidArgumentAn invalid signature, a view call to a function that is not a view, or a read mask path the node does not know
UnavailableThe node is unreachable, or getHealth found its latest checkpoint too old
CanceledThe call's signal was aborted

Handle errors​

Wrap the call in try/catch for whole-call failures, and check ok on each result of a batch:

import { Code } from '@connectrpc/connect';
import { decodeObject, ServerError, TransportError } from '@iota/grpc';

try {
const { body } = await client.getObjects(ids);

for (const result of body) {
if (result.ok) {
use(decodeObject(result.value));
} else if (result.error instanceof ServerError && result.error.code === Code.NotFound) {
console.log('missing');
} else {
throw result.error;
}
}
} catch (error) {
if (error instanceof TransportError && error.code === Code.Unavailable) {
// Retry later, or try another node.
}
throw error;
}

Some failures do not throw at all. A transaction that executes but fails comes back with a Failed status in its effects, and a view function that aborts comes back with an executionError. See Simulate and Execute Transactions and Call Move View Functions.