EdgeAIG's picture
download
raw
13.1 kB
/**
* Defines structured failures for SQL clients and driver integrations.
*
* `SqlError` wraps the different reasons a SQL operation can fail, such as
* connection, authentication, authorization, syntax, constraint, or transaction
* problems. Each reason keeps the original cause, optional message and
* operation metadata, and whether retrying may succeed. This module also
* includes schemas, guards, a SQLite error classifier, and the
* `ResultLengthMismatch` error used by ordered batched SQL resolvers.
*
* @since 4.0.0
*/
import * as Predicate from "../../Predicate.js";
import * as Schema from "../../Schema.js";
const TypeId = "~effect/sql/SqlError";
const ReasonTypeId = "~effect/sql/SqlError/Reason";
const ReasonFields = {
cause: /*#__PURE__*/Schema.Defect(),
message: /*#__PURE__*/Schema.optional(Schema.String),
operation: /*#__PURE__*/Schema.optional(Schema.String)
};
/**
* SQL error reason for connection or open failures; marked retryable.
*
* @category errors
* @since 4.0.0
*/
export class ConnectionError extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError/ConnectionError")("ConnectionError", ReasonFields) {
/**
* Marks this value as a structured SQL error reason for runtime guards.
*
* @since 4.0.0
*/
[ReasonTypeId] = ReasonTypeId;
/**
* Indicates whether retrying the failed SQL operation may succeed.
*
* @since 4.0.0
*/
get isRetryable() {
return true;
}
}
/**
* SQL error reason for authentication failures such as invalid credentials; not
* marked retryable.
*
* @category errors
* @since 4.0.0
*/
export class AuthenticationError extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError/AuthenticationError")("AuthenticationError", ReasonFields) {
/**
* Marks this value as a structured SQL error reason for runtime guards.
*
* @since 4.0.0
*/
[ReasonTypeId] = ReasonTypeId;
/**
* Indicates whether retrying the failed SQL operation may succeed.
*
* @since 4.0.0
*/
get isRetryable() {
return false;
}
}
/**
* SQL error reason for authorization or permission failures; not marked
* retryable.
*
* @category errors
* @since 4.0.0
*/
export class AuthorizationError extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError/AuthorizationError")("AuthorizationError", ReasonFields) {
/**
* Marks this value as a structured SQL error reason for runtime guards.
*
* @since 4.0.0
*/
[ReasonTypeId] = ReasonTypeId;
/**
* Indicates whether retrying the failed SQL operation may succeed.
*
* @since 4.0.0
*/
get isRetryable() {
return false;
}
}
/**
* SQL error reason for invalid SQL syntax; not marked retryable.
*
* @category errors
* @since 4.0.0
*/
export class SqlSyntaxError extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError/SqlSyntaxError")("SqlSyntaxError", ReasonFields) {
/**
* Marks this value as a structured SQL error reason for runtime guards.
*
* @since 4.0.0
*/
[ReasonTypeId] = ReasonTypeId;
/**
* Indicates whether retrying the failed SQL operation may succeed.
*
* @since 4.0.0
*/
get isRetryable() {
return false;
}
}
const UniqueViolationFields = {
...ReasonFields,
constraint: Schema.String
};
/**
* SQL error reason for a unique constraint violation, including the violated
* constraint identifier; not marked retryable.
*
* @category errors
* @since 4.0.0
*/
export class UniqueViolation extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError/UniqueViolation")("UniqueViolation", UniqueViolationFields) {
/**
* Marks this value as a structured SQL error reason for runtime guards.
*
* @since 4.0.0
*/
[ReasonTypeId] = ReasonTypeId;
/**
* Indicates whether retrying the failed SQL operation may succeed.
*
* @since 4.0.0
*/
get isRetryable() {
return false;
}
}
/**
* SQL error reason for a non-unique constraint violation; not marked retryable.
*
* @category errors
* @since 4.0.0
*/
export class ConstraintError extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError/ConstraintError")("ConstraintError", ReasonFields) {
/**
* Marks this value as a structured SQL error reason for runtime guards.
*
* @since 4.0.0
*/
[ReasonTypeId] = ReasonTypeId;
/**
* Indicates whether retrying the failed SQL operation may succeed.
*
* @since 4.0.0
*/
get isRetryable() {
return false;
}
}
/**
* SQL error reason for a database deadlock; marked retryable.
*
* @category errors
* @since 4.0.0
*/
export class DeadlockError extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError/DeadlockError")("DeadlockError", ReasonFields) {
/**
* Marks this value as a structured SQL error reason for runtime guards.
*
* @since 4.0.0
*/
[ReasonTypeId] = ReasonTypeId;
/**
* Indicates whether retrying the failed SQL operation may succeed.
*
* @since 4.0.0
*/
get isRetryable() {
return true;
}
}
/**
* SQL error reason for a transaction serialization or isolation conflict;
* marked retryable.
*
* @category errors
* @since 4.0.0
*/
export class SerializationError extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError/SerializationError")("SerializationError", ReasonFields) {
/**
* Marks this value as a structured SQL error reason for runtime guards.
*
* @since 4.0.0
*/
[ReasonTypeId] = ReasonTypeId;
/**
* Indicates whether retrying the failed SQL operation may succeed.
*
* @since 4.0.0
*/
get isRetryable() {
return true;
}
}
/**
* SQL error reason for timing out while waiting on a database lock; marked
* retryable.
*
* @category errors
* @since 4.0.0
*/
export class LockTimeoutError extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError/LockTimeoutError")("LockTimeoutError", ReasonFields) {
/**
* Marks this value as a structured SQL error reason for runtime guards.
*
* @since 4.0.0
*/
[ReasonTypeId] = ReasonTypeId;
/**
* Indicates whether retrying the failed SQL operation may succeed.
*
* @since 4.0.0
*/
get isRetryable() {
return true;
}
}
/**
* SQL error reason for a statement or query timeout; marked retryable.
*
* @category errors
* @since 4.0.0
*/
export class StatementTimeoutError extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError/StatementTimeoutError")("StatementTimeoutError", ReasonFields) {
/**
* Marks this value as a structured SQL error reason for runtime guards.
*
* @since 4.0.0
*/
[ReasonTypeId] = ReasonTypeId;
/**
* Indicates whether retrying the failed SQL operation may succeed.
*
* @since 4.0.0
*/
get isRetryable() {
return true;
}
}
/**
* SQL error reason for an unclassified database failure; not marked retryable.
*
* @category errors
* @since 4.0.0
*/
export class UnknownError extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError/UnknownError")("UnknownError", ReasonFields) {
/**
* Marks this value as a structured SQL error reason for runtime guards.
*
* @since 4.0.0
*/
[ReasonTypeId] = ReasonTypeId;
/**
* Indicates whether retrying the failed SQL operation may succeed.
*
* @since 4.0.0
*/
get isRetryable() {
return false;
}
}
/**
* Schema for encoding and decoding SQL error reasons.
*
* @category schemas
* @since 4.0.0
*/
export const SqlErrorReason = /*#__PURE__*/Schema.Union([ConnectionError, AuthenticationError, AuthorizationError, SqlSyntaxError, UniqueViolation, ConstraintError, DeadlockError, SerializationError, LockTimeoutError, StatementTimeoutError, UnknownError]);
/**
* Error wrapper for SQL failures whose `message`, `cause`, and `isRetryable`
* values are derived from its `SqlErrorReason`.
*
* @category errors
* @since 4.0.0
*/
export class SqlError extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/SqlError")("SqlError", {
reason: SqlErrorReason
}) {
/**
* Marks this value as the top-level SQL error wrapper for runtime guards.
*
* @since 4.0.0
*/
[TypeId] = TypeId;
/**
* Exposes the structured SQL reason as the JavaScript error cause.
*
* @since 4.0.0
*/
cause = this.reason;
/**
* Uses the reason message when present, otherwise falls back to the reason tag.
*
* @since 4.0.0
*/
get message() {
return this.reason.message || this.reason._tag;
}
/**
* Delegates retryability to the underlying SQL error reason.
*
* @since 4.0.0
*/
get isRetryable() {
return this.reason.isRetryable;
}
}
/**
* Returns `true` when a value is a `SqlError`.
*
* @category guards
* @since 4.0.0
*/
export const isSqlError = u => Predicate.hasProperty(u, TypeId);
/**
* Returns `true` when a value is a `SqlErrorReason`.
*
* @category guards
* @since 4.0.0
*/
export const isSqlErrorReason = u => Predicate.hasProperty(u, ReasonTypeId);
const sqliteCodeFromCause = cause => {
if (!Predicate.hasProperty(cause, "code")) {
return undefined;
}
const code = cause.code;
return typeof code === "string" || typeof code === "number" ? code : undefined;
};
const sqliteNumericCodeFromCause = cause => {
const code = sqliteCodeFromCause(cause);
if (typeof code === "number") {
return code;
}
if (!Predicate.hasProperty(cause, "errno")) {
return undefined;
}
const errno = cause.errno;
return typeof errno === "number" ? errno : undefined;
};
const matchesSqliteNumericCode = (cause, expected) => {
const code = sqliteCodeFromCause(cause);
if (code === expected) {
return true;
}
if (!Predicate.hasProperty(cause, "errno")) {
return false;
}
return cause.errno === expected;
};
const matchesSqliteCode = (code, expected) => code === expected || code.startsWith(expected + "_");
const UNKNOWN_CONSTRAINT = "unknown";
const SQLITE_CONSTRAINT_UNIQUE = "SQLITE_CONSTRAINT_UNIQUE";
const SQLITE_CONSTRAINT_UNIQUE_CODE = 2067;
const normalizeConstraintIdentifier = identifier => {
if (typeof identifier !== "string") {
return UNKNOWN_CONSTRAINT;
}
const trimmed = identifier.trim();
return trimmed.length === 0 ? UNKNOWN_CONSTRAINT : trimmed;
};
const sqliteUniqueConstraintFromCause = cause => {
if (Predicate.hasProperty(cause, "constraint")) {
return normalizeConstraintIdentifier(cause.constraint);
}
if (!Predicate.hasProperty(cause, "message")) {
return UNKNOWN_CONSTRAINT;
}
const message = cause.message;
if (typeof message !== "string") {
return UNKNOWN_CONSTRAINT;
}
const prefix = "UNIQUE constraint failed:";
const index = message.indexOf(prefix);
return index === -1 ? UNKNOWN_CONSTRAINT : normalizeConstraintIdentifier(message.slice(index + prefix.length));
};
/**
* Classifies a native SQLite error cause into a `SqlErrorReason` using its
* `code` or `errno`, with optional message and operation metadata.
*
* @category converting
* @since 4.0.0
*/
export const classifySqliteError = (cause, {
message,
operation
} = {}) => {
const props = {
cause,
message,
operation
};
const code = sqliteCodeFromCause(cause);
const numericCode = sqliteNumericCodeFromCause(cause);
if (code === SQLITE_CONSTRAINT_UNIQUE || matchesSqliteNumericCode(cause, SQLITE_CONSTRAINT_UNIQUE_CODE)) {
return new UniqueViolation({
...props,
constraint: sqliteUniqueConstraintFromCause(cause)
});
}
if (typeof code === "string") {
if (matchesSqliteCode(code, "SQLITE_AUTH")) {
return new AuthenticationError(props);
}
if (matchesSqliteCode(code, "SQLITE_PERM")) {
return new AuthorizationError(props);
}
if (matchesSqliteCode(code, "SQLITE_CONSTRAINT")) {
return new ConstraintError(props);
}
if (matchesSqliteCode(code, "SQLITE_BUSY") || matchesSqliteCode(code, "SQLITE_LOCKED")) {
return new LockTimeoutError(props);
}
if (matchesSqliteCode(code, "SQLITE_CANTOPEN")) {
return new ConnectionError(props);
}
}
if (typeof numericCode === "number") {
const code = numericCode & 0xff;
switch (code) {
case 23:
return new AuthenticationError(props);
case 3:
return new AuthorizationError(props);
case 19:
return new ConstraintError(props);
case 5:
case 6:
return new LockTimeoutError(props);
case 14:
return new ConnectionError(props);
default:
return new UnknownError(props);
}
}
return new UnknownError(props);
};
/**
* Error raised when an ordered batched SQL resolver receives a different number
* of result rows than requests.
*
* @category errors
* @since 4.0.0
*/
export class ResultLengthMismatch extends /*#__PURE__*/Schema.TaggedErrorClass("effect/sql/ResultLengthMismatch")("ResultLengthMismatch", {
expected: Schema.Number,
actual: Schema.Number
}) {
/**
* Explains the mismatch between expected and actual batched SQL result counts.
*
* @since 4.0.0
*/
get message() {
return `Expected ${this.expected} results but got ${this.actual}`;
}
}
//# sourceMappingURL=SqlError.js.map

Xet Storage Details

Size:
13.1 kB
·
Xet hash:
3bbbe44103ac0172c4bbc15904dec380ad281a9ba9a1a805856f5b66ba233aa2

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.