UNPKG

@dfinity/agent

Version:

JavaScript and TypeScript library to interact with the Internet Computer

609 lines 22 kB
import { bytesToHex } from '@noble/hashes/utils'; export var ErrorKindEnum; (function (ErrorKindEnum) { ErrorKindEnum["Trust"] = "Trust"; ErrorKindEnum["Protocol"] = "Protocol"; ErrorKindEnum["Reject"] = "Reject"; ErrorKindEnum["Transport"] = "Transport"; ErrorKindEnum["External"] = "External"; ErrorKindEnum["Limit"] = "Limit"; ErrorKindEnum["Input"] = "Input"; ErrorKindEnum["Unknown"] = "Unknown"; })(ErrorKindEnum || (ErrorKindEnum = {})); class ErrorCode { constructor(isCertified = false) { this.isCertified = isCertified; } toString() { let errorMessage = this.toErrorMessage(); if (this.requestContext) { errorMessage += `\nRequest context:\n` + ` Request ID (hex): ${this.requestContext.requestId ? bytesToHex(this.requestContext.requestId) : 'undefined'}\n` + ` Sender pubkey (hex): ${bytesToHex(this.requestContext.senderPubKey)}\n` + ` Sender signature (hex): ${bytesToHex(this.requestContext.senderSignature)}\n` + ` Ingress expiry: ${this.requestContext.ingressExpiry.toString()}`; } if (this.callContext) { errorMessage += `\nCall context:\n` + ` Canister ID: ${this.callContext.canisterId.toText()}\n` + ` Method name: ${this.callContext.methodName}\n` + ` HTTP details: ${JSON.stringify(this.callContext.httpDetails, null, 2)}`; } return errorMessage; } } /** * An error that happens in the Agent. This is the root of all errors and should be used * everywhere in the Agent code (this package). * * To know if the error is certified, use the `isCertified` getter. */ export class AgentError extends Error { get code() { return this.cause.code; } set code(code) { this.cause.code = code; } get kind() { return this.cause.kind; } set kind(kind) { this.cause.kind = kind; } /** * Reads the `isCertified` property of the underlying error code. * @returns `true` if the error is certified, `false` otherwise. */ get isCertified() { return this.code.isCertified; } constructor(code, kind) { super(code.toString()); this.name = 'AgentError'; this.cause = { code, kind }; Object.setPrototypeOf(this, AgentError.prototype); } hasCode(code) { return this.code instanceof code; } toString() { return `${this.name} (${this.kind}): ${this.message}`; } } class ErrorKind extends AgentError { static fromCode(code) { return new this(code); } } export class TrustError extends ErrorKind { constructor(code) { super(code, ErrorKindEnum.Trust); this.name = 'TrustError'; Object.setPrototypeOf(this, TrustError.prototype); } } export class ProtocolError extends ErrorKind { constructor(code) { super(code, ErrorKindEnum.Protocol); this.name = 'ProtocolError'; Object.setPrototypeOf(this, ProtocolError.prototype); } } export class RejectError extends ErrorKind { constructor(code) { super(code, ErrorKindEnum.Reject); this.name = 'RejectError'; Object.setPrototypeOf(this, RejectError.prototype); } } export class TransportError extends ErrorKind { constructor(code) { super(code, ErrorKindEnum.Transport); this.name = 'TransportError'; Object.setPrototypeOf(this, TransportError.prototype); } } export class ExternalError extends ErrorKind { constructor(code) { super(code, ErrorKindEnum.External); this.name = 'ExternalError'; Object.setPrototypeOf(this, ExternalError.prototype); } } export class LimitError extends ErrorKind { constructor(code) { super(code, ErrorKindEnum.Limit); this.name = 'LimitError'; Object.setPrototypeOf(this, LimitError.prototype); } } export class InputError extends ErrorKind { constructor(code) { super(code, ErrorKindEnum.Input); this.name = 'InputError'; Object.setPrototypeOf(this, InputError.prototype); } } export class UnknownError extends ErrorKind { constructor(code) { super(code, ErrorKindEnum.Unknown); this.name = 'UnknownError'; Object.setPrototypeOf(this, UnknownError.prototype); } } export class CertificateVerificationErrorCode extends ErrorCode { constructor(reason) { super(); this.reason = reason; this.name = 'CertificateVerificationErrorCode'; Object.setPrototypeOf(this, CertificateVerificationErrorCode.prototype); } toErrorMessage() { return `Certificate verification error: "${this.reason}"`; } } export class CertificateTimeErrorCode extends ErrorCode { constructor(maxAgeInMinutes, certificateTime, currentTime, ageType) { super(); this.maxAgeInMinutes = maxAgeInMinutes; this.certificateTime = certificateTime; this.currentTime = currentTime; this.ageType = ageType; this.name = 'CertificateTimeErrorCode'; Object.setPrototypeOf(this, CertificateTimeErrorCode.prototype); } toErrorMessage() { return `Certificate is signed more than ${this.maxAgeInMinutes} minutes in the ${this.ageType}. Certificate time: ${this.certificateTime.toISOString()} Current time: ${this.currentTime.toISOString()}`; } } export class CertificateHasTooManyDelegationsErrorCode extends ErrorCode { constructor() { super(); this.name = 'CertificateHasTooManyDelegationsErrorCode'; Object.setPrototypeOf(this, CertificateHasTooManyDelegationsErrorCode.prototype); } toErrorMessage() { return 'Certificate has too many delegations'; } } export class CertificateNotAuthorizedErrorCode extends ErrorCode { constructor(canisterId, subnetId) { super(); this.canisterId = canisterId; this.subnetId = subnetId; this.name = 'CertificateNotAuthorizedErrorCode'; Object.setPrototypeOf(this, CertificateNotAuthorizedErrorCode.prototype); } toErrorMessage() { return `The certificate contains a delegation that does not include the canister ${this.canisterId.toText()} in the canister_ranges field. Subnet ID: 0x${bytesToHex(this.subnetId)}`; } } export class LookupErrorCode extends ErrorCode { constructor(message, lookupStatus) { super(); this.message = message; this.lookupStatus = lookupStatus; this.name = 'LookupErrorCode'; Object.setPrototypeOf(this, LookupErrorCode.prototype); } toErrorMessage() { return `${this.message}. Lookup status: ${this.lookupStatus}`; } } export class MalformedLookupFoundValueErrorCode extends ErrorCode { constructor(message) { super(); this.message = message; this.name = 'MalformedLookupFoundValueErrorCode'; Object.setPrototypeOf(this, MalformedLookupFoundValueErrorCode.prototype); } toErrorMessage() { return this.message; } } export class MissingLookupValueErrorCode extends ErrorCode { constructor(message) { super(); this.message = message; this.name = 'MissingLookupValueErrorCode'; Object.setPrototypeOf(this, MissingLookupValueErrorCode.prototype); } toErrorMessage() { return this.message; } } export class DerKeyLengthMismatchErrorCode extends ErrorCode { constructor(expectedLength, actualLength) { super(); this.expectedLength = expectedLength; this.actualLength = actualLength; this.name = 'DerKeyLengthMismatchErrorCode'; Object.setPrototypeOf(this, DerKeyLengthMismatchErrorCode.prototype); } toErrorMessage() { return `BLS DER-encoded public key must be ${this.expectedLength} bytes long, but is ${this.actualLength} bytes long`; } } export class DerPrefixMismatchErrorCode extends ErrorCode { constructor(expectedPrefix, actualPrefix) { super(); this.expectedPrefix = expectedPrefix; this.actualPrefix = actualPrefix; this.name = 'DerPrefixMismatchErrorCode'; Object.setPrototypeOf(this, DerPrefixMismatchErrorCode.prototype); } toErrorMessage() { return `BLS DER-encoded public key is invalid. Expected the following prefix: ${bytesToHex(this.expectedPrefix)}, but got ${bytesToHex(this.actualPrefix)}`; } } export class DerDecodeLengthMismatchErrorCode extends ErrorCode { constructor(expectedLength, actualLength) { super(); this.expectedLength = expectedLength; this.actualLength = actualLength; this.name = 'DerDecodeLengthMismatchErrorCode'; Object.setPrototypeOf(this, DerDecodeLengthMismatchErrorCode.prototype); } toErrorMessage() { return `DER payload mismatch: Expected length ${this.expectedLength}, actual length: ${this.actualLength}`; } } export class DerDecodeErrorCode extends ErrorCode { constructor(error) { super(); this.error = error; this.name = 'DerDecodeErrorCode'; Object.setPrototypeOf(this, DerDecodeErrorCode.prototype); } toErrorMessage() { return `Failed to decode DER: ${this.error}`; } } export class DerEncodeErrorCode extends ErrorCode { constructor(error) { super(); this.error = error; this.name = 'DerEncodeErrorCode'; Object.setPrototypeOf(this, DerEncodeErrorCode.prototype); } toErrorMessage() { return `Failed to encode DER: ${this.error}`; } } export class CborDecodeErrorCode extends ErrorCode { constructor(error, input) { super(); this.error = error; this.input = input; this.name = 'CborDecodeErrorCode'; Object.setPrototypeOf(this, CborDecodeErrorCode.prototype); } toErrorMessage() { return `Failed to decode CBOR: ${this.error}, input: ${bytesToHex(this.input)}`; } } export class CborEncodeErrorCode extends ErrorCode { constructor(error, value) { super(); this.error = error; this.value = value; this.name = 'CborEncodeErrorCode'; Object.setPrototypeOf(this, CborEncodeErrorCode.prototype); } toErrorMessage() { return `Failed to encode CBOR: ${this.error}, input: ${this.value}`; } } export class HexDecodeErrorCode extends ErrorCode { constructor(error) { super(); this.error = error; this.name = 'HexDecodeErrorCode'; Object.setPrototypeOf(this, HexDecodeErrorCode.prototype); } toErrorMessage() { return `Failed to decode hex: ${this.error}`; } } export class TimeoutWaitingForResponseErrorCode extends ErrorCode { constructor(message, requestId, status) { super(); this.message = message; this.requestId = requestId; this.status = status; this.name = 'TimeoutWaitingForResponseErrorCode'; Object.setPrototypeOf(this, TimeoutWaitingForResponseErrorCode.prototype); } toErrorMessage() { let errorMessage = `${this.message}\n`; if (this.requestId) { errorMessage += ` Request ID: ${bytesToHex(this.requestId)}\n`; } if (this.status) { errorMessage += ` Request status: ${this.status}\n`; } return errorMessage; } } export class CertificateOutdatedErrorCode extends ErrorCode { constructor(maxIngressExpiryInMinutes, requestId, retryTimes) { super(); this.maxIngressExpiryInMinutes = maxIngressExpiryInMinutes; this.requestId = requestId; this.retryTimes = retryTimes; this.name = 'CertificateOutdatedErrorCode'; Object.setPrototypeOf(this, CertificateOutdatedErrorCode.prototype); } toErrorMessage() { let errorMessage = `Certificate is stale (over ${this.maxIngressExpiryInMinutes} minutes). Is the computer's clock synchronized?\n Request ID: ${bytesToHex(this.requestId)}\n`; if (this.retryTimes !== undefined) { errorMessage += ` Retried ${this.retryTimes} times.`; } return errorMessage; } } export class CertifiedRejectErrorCode extends ErrorCode { constructor(requestId, rejectCode, rejectMessage, rejectErrorCode) { super(true); this.requestId = requestId; this.rejectCode = rejectCode; this.rejectMessage = rejectMessage; this.rejectErrorCode = rejectErrorCode; this.name = 'CertifiedRejectErrorCode'; Object.setPrototypeOf(this, CertifiedRejectErrorCode.prototype); } toErrorMessage() { return (`The replica returned a rejection error:\n` + ` Request ID: ${bytesToHex(this.requestId)}\n` + ` Reject code: ${this.rejectCode}\n` + ` Reject text: ${this.rejectMessage}\n` + ` Error code: ${this.rejectErrorCode}\n`); } } export class UncertifiedRejectErrorCode extends ErrorCode { constructor(requestId, rejectCode, rejectMessage, rejectErrorCode, signatures) { super(); this.requestId = requestId; this.rejectCode = rejectCode; this.rejectMessage = rejectMessage; this.rejectErrorCode = rejectErrorCode; this.signatures = signatures; this.name = 'UncertifiedRejectErrorCode'; Object.setPrototypeOf(this, UncertifiedRejectErrorCode.prototype); } toErrorMessage() { return (`The replica returned a rejection error:\n` + ` Request ID: ${bytesToHex(this.requestId)}\n` + ` Reject code: ${this.rejectCode}\n` + ` Reject text: ${this.rejectMessage}\n` + ` Error code: ${this.rejectErrorCode}\n`); } } export class RequestStatusDoneNoReplyErrorCode extends ErrorCode { constructor(requestId) { super(); this.requestId = requestId; this.name = 'RequestStatusDoneNoReplyErrorCode'; Object.setPrototypeOf(this, RequestStatusDoneNoReplyErrorCode.prototype); } toErrorMessage() { return (`Call was marked as done but we never saw the reply:\n` + ` Request ID: ${bytesToHex(this.requestId)}\n`); } } export class MissingRootKeyErrorCode extends ErrorCode { constructor(shouldFetchRootKey) { super(); this.shouldFetchRootKey = shouldFetchRootKey; this.name = 'MissingRootKeyErrorCode'; Object.setPrototypeOf(this, MissingRootKeyErrorCode.prototype); } toErrorMessage() { if (this.shouldFetchRootKey === undefined) { return 'Agent is missing root key'; } return `Agent is missing root key and the shouldFetchRootKey value is set to ${this.shouldFetchRootKey}. The root key should only be unknown if you are in local development. Otherwise you should avoid fetching and use the default IC Root Key or the known root key of your environment.`; } } export class HashValueErrorCode extends ErrorCode { constructor(value) { super(); this.value = value; this.name = 'HashValueErrorCode'; Object.setPrototypeOf(this, HashValueErrorCode.prototype); } toErrorMessage() { return `Attempt to hash a value of unsupported type: ${this.value}`; } } export class HttpDefaultFetchErrorCode extends ErrorCode { constructor(error) { super(); this.error = error; this.name = 'HttpDefaultFetchErrorCode'; Object.setPrototypeOf(this, HttpDefaultFetchErrorCode.prototype); } toErrorMessage() { return this.error; } } export class IdentityInvalidErrorCode extends ErrorCode { constructor() { super(); this.name = 'IdentityInvalidErrorCode'; Object.setPrototypeOf(this, IdentityInvalidErrorCode.prototype); } toErrorMessage() { return "This identity has expired due this application's security policy. Please refresh your authentication."; } } export class IngressExpiryInvalidErrorCode extends ErrorCode { constructor(message, providedIngressExpiryInMinutes) { super(); this.message = message; this.providedIngressExpiryInMinutes = providedIngressExpiryInMinutes; this.name = 'IngressExpiryInvalidErrorCode'; Object.setPrototypeOf(this, IngressExpiryInvalidErrorCode.prototype); } toErrorMessage() { return `${this.message}. Provided ingress expiry time is ${this.providedIngressExpiryInMinutes} minutes.`; } } export class CreateHttpAgentErrorCode extends ErrorCode { constructor() { super(); this.name = 'CreateHttpAgentErrorCode'; Object.setPrototypeOf(this, CreateHttpAgentErrorCode.prototype); } toErrorMessage() { return 'Failed to create agent from provided agent'; } } export class MalformedSignatureErrorCode extends ErrorCode { constructor(error) { super(); this.error = error; this.name = 'MalformedSignatureErrorCode'; Object.setPrototypeOf(this, MalformedSignatureErrorCode.prototype); } toErrorMessage() { return `Query response contained a malformed signature: ${this.error}`; } } export class MissingSignatureErrorCode extends ErrorCode { constructor() { super(); this.name = 'MissingSignatureErrorCode'; Object.setPrototypeOf(this, MissingSignatureErrorCode.prototype); } toErrorMessage() { return 'Query response did not contain any node signatures'; } } export class MalformedPublicKeyErrorCode extends ErrorCode { constructor() { super(); this.name = 'MalformedPublicKeyErrorCode'; Object.setPrototypeOf(this, MalformedPublicKeyErrorCode.prototype); } toErrorMessage() { return 'Read state response contained a malformed public key'; } } export class QuerySignatureVerificationFailedErrorCode extends ErrorCode { constructor(nodeId) { super(); this.nodeId = nodeId; this.name = 'QuerySignatureVerificationFailedErrorCode'; Object.setPrototypeOf(this, QuerySignatureVerificationFailedErrorCode.prototype); } toErrorMessage() { return `Query signature verification failed. Node ID: ${this.nodeId}`; } } export class UnexpectedErrorCode extends ErrorCode { constructor(error) { super(); this.error = error; this.name = 'UnexpectedErrorCode'; Object.setPrototypeOf(this, UnexpectedErrorCode.prototype); } toErrorMessage() { return `Unexpected error: ${this.error}`; } } export class HashTreeDecodeErrorCode extends ErrorCode { constructor(error) { super(); this.error = error; this.name = 'HashTreeDecodeErrorCode'; Object.setPrototypeOf(this, HashTreeDecodeErrorCode.prototype); } toErrorMessage() { return `Failed to decode certificate: ${this.error}`; } } export class HttpErrorCode extends ErrorCode { constructor(status, statusText, headers, bodyText) { super(); this.status = status; this.statusText = statusText; this.headers = headers; this.bodyText = bodyText; this.name = 'HttpErrorCode'; Object.setPrototypeOf(this, HttpErrorCode.prototype); } toErrorMessage() { let errorMessage = 'HTTP request failed:\n' + ` Status: ${this.status} (${this.statusText})\n` + ` Headers: ${JSON.stringify(this.headers)}\n`; if (this.bodyText) { errorMessage += ` Body: ${this.bodyText}\n`; } return errorMessage; } } export class HttpV3ApiNotSupportedErrorCode extends ErrorCode { constructor() { super(); this.name = 'HttpV3ApiNotSupportedErrorCode'; Object.setPrototypeOf(this, HttpV3ApiNotSupportedErrorCode.prototype); } toErrorMessage() { return 'HTTP request failed: v3 API is not supported'; } } export class HttpFetchErrorCode extends ErrorCode { constructor(error) { super(); this.error = error; this.name = 'HttpFetchErrorCode'; Object.setPrototypeOf(this, HttpFetchErrorCode.prototype); } toErrorMessage() { return `Failed to fetch HTTP request: ${this.error}`; } } export class MissingCanisterIdErrorCode extends ErrorCode { constructor(receivedCanisterId) { super(); this.receivedCanisterId = receivedCanisterId; this.name = 'MissingCanisterIdErrorCode'; Object.setPrototypeOf(this, MissingCanisterIdErrorCode.prototype); } toErrorMessage() { return `Canister ID is required, but received ${typeof this.receivedCanisterId} instead. If you are using automatically generated declarations, this may be because your application is not setting the canister ID in process.env correctly.`; } } export class InvalidReadStateRequestErrorCode extends ErrorCode { constructor(request) { super(); this.request = request; this.name = 'InvalidReadStateRequestErrorCode'; Object.setPrototypeOf(this, InvalidReadStateRequestErrorCode.prototype); } toErrorMessage() { return `Invalid read state request: ${this.request}`; } } export class ExpiryJsonDeserializeErrorCode extends ErrorCode { constructor(error) { super(); this.error = error; this.name = 'ExpiryJsonDeserializeErrorCode'; Object.setPrototypeOf(this, ExpiryJsonDeserializeErrorCode.prototype); } toErrorMessage() { return `Failed to deserialize expiry: ${this.error}`; } } /** * Special error used to indicate that a code path is unreachable. * * For internal use only. */ export const UNREACHABLE_ERROR = new Error('unreachable'); //# sourceMappingURL=errors.js.map