
//#region src/types/errors.ts
const INTERNAL_ERROR_CODE = 500;
const TIMEOUT_ERROR_CODE = 408;
const CANCEL_ERROR_CODE = 409;
const UNKNOWN_ERROR_CODE = 500;
const CLOSED_ERROR_CODE = 598;
const SUSPENDED_ERROR_CODE = 599;
function ensureError(e, asTerminalError) {
	if (e instanceof TerminalError) return e;
	const maybeTerminalError = asTerminalError ? asTerminalError(e) : void 0;
	if (maybeTerminalError) return maybeTerminalError;
	if (e instanceof Error) return e;
	if (typeof e === "object" && e !== null && "code" in e && "message" in e) return new RestateError(e.message, { errorCode: e.code });
	let msg;
	try {
		msg = JSON.stringify(e);
	} catch {
		msg = "(no JSON representation)";
	}
	return /* @__PURE__ */ new Error("Non-Error value: " + msg);
}
function logError(log, e) {
	if (e instanceof RestateError) {
		if (e.code === SUSPENDED_ERROR_CODE) {
			log.info("Invocation suspended");
			return;
		} else if (e.code === CLOSED_ERROR_CODE) {
			log.error("DANGER! The invocation is closed, but some related operation is still running. \nThis might indicate that a RestatePromise is being awaited on an asynchronous task, outside the handler, or you're awaiting a RestatePromise inside a ctx.run.\nThis is dangerous, and can lead the service to deadlock. Please fix the issue.\nDiagnostic: ", e);
			return;
		}
	}
	log.warn("Error when processing a Restate context operation.\n", e);
}
var RestateError = class extends Error {
	code;
	name = "RestateError";
	constructor(message, options) {
		super(message, { cause: options?.cause });
		this.code = options?.errorCode ?? INTERNAL_ERROR_CODE;
	}
};
/**
* Does not lead to Restate retries.
*
* Leads to an output message with a failure defined.
*/
var TerminalError = class extends RestateError {
	name = "TerminalError";
	metadata;
	constructor(message, options) {
		super(message, options);
		this.metadata = options?.metadata ?? {};
	}
};
/**
* Returned by `RestatePromise.withTimeout` when the timeout is reached.
*/
var TimeoutError = class extends TerminalError {
	name = "TimeoutError";
	constructor() {
		super("Timeout occurred", { errorCode: TIMEOUT_ERROR_CODE });
	}
};
/**
* Returned when the invocation was cancelled.
*/
var CancelledError = class extends TerminalError {
	name = "CancelledError";
	constructor() {
		super("Cancelled", { errorCode: CANCEL_ERROR_CODE });
	}
};
/**
* Error that Restate will retry. By using this error type within a `ctx.run` closure,
* you can dynamically provide the retry delay specified in {@link RetryableErrorOptions}.
*
* You can wrap another error using {@link from}.
*/
var RetryableError = class RetryableError extends RestateError {
	name = "RetryableError";
	retryAfter;
	constructor(message, options) {
		super(message, {
			errorCode: options?.errorCode,
			cause: options?.cause
		});
		this.retryAfter = options?.retryAfter;
	}
	/**
	* Create a `RetryableError` from the given cause.
	*/
	static from(cause, options) {
		const error = ensureError(cause);
		return new RetryableError(error.message, {
			errorCode: error["errorCode"],
			cause,
			...options
		});
	}
};
/**
* Returns true if the error indicates the current attempt is ending without
* a failure — e.g. the runtime suspended the invocation (waiting for
* `ctx.sleep()` or `ctx.call()`), or the connection was dropped (kill).
*
* Use this in handler interceptor catch blocks to distinguish attempt-ending
* signals from real errors (e.g. to avoid logging it as a failure or to set
* a neutral span status).
*/
function isSuspendedError(e) {
	return e instanceof RestateError && e.code === SUSPENDED_ERROR_CODE;
}

//#endregion
exports.CancelledError = CancelledError;
exports.INTERNAL_ERROR_CODE = INTERNAL_ERROR_CODE;
exports.RestateError = RestateError;
exports.RetryableError = RetryableError;
exports.TerminalError = TerminalError;
exports.TimeoutError = TimeoutError;
exports.UNKNOWN_ERROR_CODE = UNKNOWN_ERROR_CODE;
exports.ensureError = ensureError;
exports.isSuspendedError = isSuspendedError;
exports.logError = logError;