arangojs
Version:
The official ArangoDB JavaScript driver.
322 lines • 9.53 kB
JavaScript
"use strict";
/**
* ```ts
* import type { ArangoError, HttpError } from "arangojs/errors";
* ```
*
* The "errors" module provides types and interfaces for TypeScript related
* to arangojs error handling.
*
* @packageDocumentation
*/
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ArangoError = exports.HttpError = exports.FetchFailedError = exports.RequestAbortedError = exports.ResponseTimeoutError = exports.NetworkError = exports.PropagationTimeoutError = exports.isUndiciError = exports.isSystemError = exports.isNetworkError = exports.isArangoError = void 0;
const connection = __importStar(require("./connection.js"));
const codes_js_1 = require("./lib/codes.js");
/**
* Indicates whether the given value represents an {@link ArangoError}.
*
* @param error - A value that might be an `ArangoError`.
*/
function isArangoError(error) {
return Boolean(error && error.isArangoError);
}
exports.isArangoError = isArangoError;
/**
* Indicates whether the given value represents a {@link NetworkError}.
*
* @param error - A value that might be a `NetworkError`.
*/
function isNetworkError(error) {
return error instanceof NetworkError;
}
exports.isNetworkError = isNetworkError;
/**
* @internal
*
* Indicates whether the given value represents a Node.js `SystemError`.
*/
function isSystemError(err) {
if (!err || !(err instanceof Error))
return false;
if (Object.getPrototypeOf(err) !== Error.prototype)
return false;
const error = err;
if (typeof error.code !== "string")
return false;
if (typeof error.syscall !== "string")
return false;
return typeof error.errno === "number" || typeof error.errno === "string";
}
exports.isSystemError = isSystemError;
/**
* @internal
*
* Indicates whether the given value represents a Node.js `UndiciError`.
*/
function isUndiciError(err) {
if (!err || !(err instanceof Error))
return false;
const error = err;
if (typeof error.code !== "string")
return false;
return error.code.startsWith("UND_");
}
exports.isUndiciError = isUndiciError;
/**
* @internal
*
* Determines whether the given failed fetch error cause is safe to retry.
*/
function isSafeToRetryFailedFetch(error) {
if (!error || !error.cause)
return null;
let cause = error.cause;
if (isArangoError(cause) || isNetworkError(cause)) {
return cause.isSafeToRetry;
}
if (isSystemError(cause) &&
cause.syscall === "connect" &&
cause.code === "ECONNREFUSED") {
return true;
}
if (isUndiciError(cause) && cause.code === "UND_ERR_CONNECT_TIMEOUT") {
return true;
}
return isSafeToRetryFailedFetch(cause);
}
/**
* Represents an error from a deliberate timeout encountered while waiting
* for propagation.
*/
class PropagationTimeoutError extends Error {
name = "PropagationTimeoutError";
constructor(message, options = {}) {
super(message ?? "Timed out while waiting for propagation", options);
}
}
exports.PropagationTimeoutError = PropagationTimeoutError;
/**
* Represents a network error or an error encountered while performing a network request.
*/
class NetworkError extends Error {
name = "NetworkError";
/**
* Indicates whether the request that caused this error can be safely retried.
*/
isSafeToRetry;
/**
* Fetch request object.
*/
request;
constructor(message, request, options = {}) {
const { isSafeToRetry = null, ...opts } = options;
super(message, opts);
this.request = request;
this.isSafeToRetry = isSafeToRetry;
}
toJSON() {
return {
error: true,
errorMessage: this.message,
code: 0,
};
}
}
exports.NetworkError = NetworkError;
/**
* Represents an error from a deliberate timeout encountered while waiting
* for a server response.
*/
class ResponseTimeoutError extends NetworkError {
name = "ResponseTimeoutError";
constructor(message, request, options = {}) {
super(message ?? "Timed out while waiting for server response", request, options);
}
}
exports.ResponseTimeoutError = ResponseTimeoutError;
/**
* Represents an error from a request that was aborted.
*/
class RequestAbortedError extends NetworkError {
name = "RequestAbortedError";
constructor(message, request, options = {}) {
super(message ?? "Request aborted", request, options);
}
}
exports.RequestAbortedError = RequestAbortedError;
/**
* Represents an error from a failed fetch request.
*
* The root cause is often extremely difficult to determine.
*/
class FetchFailedError extends NetworkError {
name = "FetchFailedError";
constructor(message, request, options = {}) {
let isSafeToRetry = options.isSafeToRetry ?? isSafeToRetryFailedFetch(options.cause);
if (options.cause?.cause instanceof Error && options.cause.cause.message) {
message = `Fetch failed: ${options.cause.cause.message}`;
}
super(message ?? "Fetch failed", request, { ...options, isSafeToRetry });
}
}
exports.FetchFailedError = FetchFailedError;
/**
* Represents a plain HTTP error response.
*/
class HttpError extends NetworkError {
name = "HttpError";
/**
* HTTP status code of the server response.
*/
code;
/**
* Server response object.
*/
response;
/**
* @internal
*/
constructor(response, options = {}) {
super(connection.getStatusMessage(response), response.request, options);
this.response = response;
this.code = response.status;
}
toJSON() {
return {
error: true,
errorMessage: this.message,
code: this.code,
};
}
toString() {
return `${this.name} ${this.code}: ${this.message}`;
}
}
exports.HttpError = HttpError;
/**
* Represents an error returned by ArangoDB.
*/
class ArangoError extends Error {
name = "ArangoError";
/**
* Indicates whether the request that caused this error can be safely retried.
*
* @internal
*/
isSafeToRetry = null;
/**
* @internal
*/
get error() {
return true;
}
/**
* ArangoDB error code.
*
* See [ArangoDB error documentation](https://www.arangodb.com/docs/stable/appendix-error-codes.html).
*/
errorNum;
/**
* Error message accompanying the error code.
*/
get errorMessage() {
return this.message;
}
/**
* HTTP status code included in the server error response object.
*/
code;
/**
* @internal
*
* Creates a new `ArangoError` from a response object.
*/
static from(response) {
return new ArangoError(response.parsedBody, {
cause: new HttpError(response),
});
}
/**
* Creates a new `ArangoError` from an ArangoDB error response.
*/
constructor(data, options = {}) {
const { isSafeToRetry, ...opts } = options;
super(data.errorMessage, opts);
this.errorNum = data.errorNum;
this.code = data.code;
if (isSafeToRetry !== undefined) {
this.isSafeToRetry = isSafeToRetry;
}
else if (this.errorNum === codes_js_1.ERROR_ARANGO_MAINTENANCE_MODE) {
this.isSafeToRetry = true;
}
else if (this.cause instanceof NetworkError) {
this.isSafeToRetry = this.cause.isSafeToRetry;
}
}
/**
* Server response object.
*/
get response() {
const cause = this.cause;
if (cause instanceof HttpError) {
return cause.response;
}
return undefined;
}
/**
* Fetch request object.
*/
get request() {
const cause = this.cause;
if (cause instanceof NetworkError) {
return cause.request;
}
return undefined;
}
/**
* @internal
*
* Indicates that this object represents an ArangoDB error.
*/
get isArangoError() {
return true;
}
toJSON() {
return {
error: true,
errorMessage: this.errorMessage,
errorNum: this.errorNum,
code: this.code,
};
}
toString() {
return `${this.name} ${this.errorNum}: ${this.message}`;
}
}
exports.ArangoError = ArangoError;
//# sourceMappingURL=errors.js.map