From 2cf70bcc3bc5bb52aa53152c6c0566ed43f79688 Mon Sep 17 00:00:00 2001 From: Joey Bright Date: Sat, 12 Sep 2026 12:27:58 -0700 Subject: [PATCH 1/7] Add types for all possible SQLite error codes Reference for the codes: https://sqlite.org/rescode.html --- integration-tests/sqlite/src/Main.gren | 16 +- src/Gren/Kernel/Sqlite.js | 12 +- src/Sqlite.gren | 517 ++++++++++++++++++++++++- 3 files changed, 506 insertions(+), 39 deletions(-) diff --git a/integration-tests/sqlite/src/Main.gren b/integration-tests/sqlite/src/Main.gren index b93fe21..bf0de5a 100644 --- a/integration-tests/sqlite/src/Main.gren +++ b/integration-tests/sqlite/src/Main.gren @@ -54,7 +54,7 @@ tests fsPerm = , awaitError "syntax error" (Sqlite.executeScript db "SELECT *") <| \err -> test "Is right type" <| \_ -> when err is - Sqlite.GenericError _ -> + Sqlite.Error _ -> Expect.pass _ -> @@ -62,18 +62,14 @@ tests fsPerm = , awaitError "Define friends" (defineFriendsById 1 2 db) <| \err -> test "Fails due to foreign key constraints" <| \_ -> when err is - Sqlite.ForeignKeyError message -> - if String.contains "foreign key" (String.toLower message) then - Expect.pass - - else - Expect.fail "Correct error type, but message doesn't mention foreign key" + Sqlite.ConstraintError Sqlite.ForeignKeyConstraintError -> + Expect.pass _ -> Expect.fail "Failed for unknown reason" , awaitError "Too many templates" (execBadTemplate 3 db) <| \err -> test "Is invalid" <| \_ -> - Expect.equal (Sqlite.GenericError "Unknown named parameter 'id1'") err + Expect.equal (Sqlite.UnknownError "Unknown named parameter 'id1'") err , await "Closing the database" (Sqlite.close db) <| \_ -> test "Works" <| \_ -> Expect.pass @@ -203,11 +199,11 @@ tests fsPerm = , awaitError "Define same friends again" (defineFriends robin.name justin.name db) <| \err -> test "Fails due to unique constraint" <| \_ -> when err is - Sqlite.UniqueConstraintError _ -> + Sqlite.ConstraintError Sqlite.UniqueConstraintError -> Expect.pass _ -> - Expect.fail ("Expected UniqueConstraintError, but got: " ++ Sqlite.errorToString err) + Expect.fail ("Expected UniqueConstraintError") ] ] , await "Open db for executeAll tests" createTestDb <| \db -> diff --git a/src/Gren/Kernel/Sqlite.js b/src/Gren/Kernel/Sqlite.js index b193a46..57f35e3 100644 --- a/src/Gren/Kernel/Sqlite.js +++ b/src/Gren/Kernel/Sqlite.js @@ -1,6 +1,6 @@ /* -import Sqlite exposing (GenericError, ForeignKeyError, UniqueConstraintError, DecodingError, MultipleResultsError) +import Sqlite exposing (errorCodeToError, GenericError, ForeignKeyError, UniqueConstraintError, DecodingError, MultipleResultsError) import Gren.Kernel.FilePath exposing (toString) import Gren.Kernel.Scheduler exposing (binding, succeed, fail) import Gren.Kernel.Json exposing (wrap, unwrap) @@ -255,13 +255,5 @@ var _Sqlite_executeScript = F2(function (script, db) { }); var _Sqlite_constructError = function (e) { - if (e.errcode === 787) { - return __Scheduler_fail(__Sqlite_ForeignKeyError(e.message)); - } - - if (e.errcode === 2067) { - return __Scheduler_fail(__Sqlite_UniqueConstraintError(e.message)); - } - - return __Scheduler_fail(__Sqlite_GenericError(e.message)); + return __Scheduler_fail(A2(__Sqlite_errorCodeToError, e.errcode, e.message)); }; diff --git a/src/Sqlite.gren b/src/Sqlite.gren index 08f84b5..4a7abfd 100644 --- a/src/Sqlite.gren +++ b/src/Sqlite.gren @@ -218,33 +218,512 @@ inTransaction db f = -- ERRORS --- TODO: How detailed should we be with errors? +{-|-} type Error - = GenericError String + = AbortError AbortError + | AuthError AuthError + | BusyError BusyError + | CantOpenError CantOpenError + | ConstraintError ConstraintError + | CorruptError CorruptError + | Error GenericError + | IoError IoError + | LockedError LockedError + | MismatchError + | MisuseError + | NoLfsError + | NoMemError + | NotADbError + | NotFoundError + | NoticeError NoticeError + | PermError + | ProtocolError + | RangeError + | ReadOnlyError ReadOnlyError + | FullError + | InternalError + | InterruptError + | TooBigError | NoResultsError + | SchemaError | MultipleResultsError Int - | ForeignKeyError String - | UniqueConstraintError String | DecodingError Decode.Error + | UnknownError String + + +{-|-} +type AbortError + = GenericAbortError String + | RollbackAbortError + + +{-|-} +type AuthError + = GenericAuthError String + | UserAuthError + + +{-|-} +type BusyError + = GenericBusyError String + | RecoveryBusyError + | SnapshotBusyError + | TimeoutBusyError + + +{-|-} +type CantOpenError + = GenericCantOpenError String + | ConvPathCantOpenError + | DirtyWalCantOpenError + | FullPathCantOpenError + | IsDirCantOpenError + | NoTempDirCantOpenError + | SymLinkCantOpenError + + +{-|-} +type ConstraintError + = GenericConstraintError String + | CheckConstraintError + | CommitHookConstraintError + | DataTypeConstraintError + | ForeignKeyConstraintError + | FunctionConstraintError + | NotNullConstraintError + | PinnedConstraintError + | PrimaryKeyConstraintError + | RowIdConstraintError + | TriggerConstraintError + | UniqueConstraintError + | VTabConstraintError + + +{-|-} +type CorruptError + = GenericCorruptError String + | IndexCorruptError + | SequenceCorruptError + | VTabCorruptError + + +{-|-} +type GenericError + = GenericError String + | MissingCollSeqGenericError + | RetryGenericError + | SnapshotGenericError + + +{-|-} +type IoError + = GenericIoError String + | AccessIoError + | AuthIoError + | BeginAtomicIoError + | BlockedIoError + | CheckReservedLockIoError + | CloseIoError + | CommitAtomicIoError + | ConvPathIoError + | CorruptFsIoError + | DataIoError + | DeleteIoError + | DeleteNoEntIoError + | DirectoryCloseIoError + | DirFSyncIoError + | FStatIoError + | FSyncIoError + | GetTempPathIoError + | LockIoError + | MMapIoError + | NoMemIoError + | RdLockIoError + | ReadIoError + | RollbackAtomicIoError + | SeekIoError + | ShmLockIoError + | ShmMapIoError + | ShmOpenIoError + | ShmSizeIoError + | ShortReadIoError + | TruncateIoError + | UnlockIoError + | VNodeIoError + | WriteIoError + + +{-|-} +type LockedError + = GenericLockedError String + | SharedCacheLockedError + | VTabLockedError + + +{-|-} +type NoticeError + = GenericNoticeError String + | RecoverRollbackNoticeError + | RecoverWalNoticeError + + +{-|-} +type ReadOnlyError + = GenericReadOnlyError String + | CantInitReadOnlyError + | CantLockReadOnlyError + | DbMovedReadOnlyError + | DirectoryReadOnlyError + | RecoveryReadOnlyError + | RollbackReadOnlyError + + +{-|-} +errorCodeToError : Int -> String -> Error +errorCodeToError errorCode message = + when errorCode is + -- Abort errors + + 4 -> + AbortError (GenericAbortError message) + + 516 -> + AbortError RollbackAbortError + + -- Auth errors + + 23 -> + AuthError (GenericAuthError message) + + 279 -> + AuthError UserAuthError + + -- Busy errors + + 5 -> + BusyError (GenericBusyError message) + + 261 -> + BusyError RecoveryBusyError + + 517 -> + BusyError SnapshotBusyError + + 773 -> + BusyError TimeoutBusyError + + -- Can't open errors + + 14 -> + CantOpenError (GenericCantOpenError message) + + 1038 -> + CantOpenError ConvPathCantOpenError + + 1294 -> + CantOpenError DirtyWalCantOpenError + + 782 -> + CantOpenError FullPathCantOpenError + + 526 -> + CantOpenError IsDirCantOpenError + + 270 -> + CantOpenError NoTempDirCantOpenError + + 1550 -> + CantOpenError SymLinkCantOpenError + + -- Constraint errors + + 19 -> + ConstraintError (GenericConstraintError message) + + 275 -> + ConstraintError CheckConstraintError + + 531 -> + ConstraintError CommitHookConstraintError + + 3091 -> + ConstraintError DataTypeConstraintError + + 787 -> + ConstraintError ForeignKeyConstraintError + + 1043 -> + ConstraintError FunctionConstraintError + + 1299 -> + ConstraintError NotNullConstraintError + + 2835 -> + ConstraintError PrimaryKeyConstraintError + + 1555 -> + ConstraintError PrimaryKeyConstraintError + + 2579 -> + ConstraintError RowIdConstraintError + + 1811 -> + ConstraintError TriggerConstraintError + + 2067 -> + ConstraintError UniqueConstraintError + + 2323 -> + ConstraintError VTabConstraintError + + -- Corrupt errors + + 11 -> + CorruptError (GenericCorruptError message) + + 779 -> + CorruptError IndexCorruptError + + 523 -> + CorruptError SequenceCorruptError + + 267 -> + CorruptError VTabCorruptError + + -- Error + + 1 -> + Error (GenericError message) + + 257 -> + Error MissingCollSeqGenericError + + 513 -> + Error RetryGenericError + + 769 -> + Error SnapshotGenericError + + -- Full error + + 13 -> + FullError + + -- Internal error + + 2 -> + InternalError + + -- Interrupt Error + + 9 -> + InterruptError + + -- IO errors + + 10 -> + IoError (GenericIoError message) + + 3338 -> + IoError AccessIoError + + 7178 -> + IoError AuthIoError + + 7434 -> + IoError BeginAtomicIoError + + 2826 -> + IoError BlockedIoError + + 3594 -> + IoError CheckReservedLockIoError + + 4106 -> + IoError CloseIoError + + 7690 -> + IoError CommitAtomicIoError + + 6666 -> + IoError ConvPathIoError + + 8458 -> + IoError CorruptFsIoError + + 8202 -> + IoError DataIoError + + 2570 -> + IoError DeleteIoError + + 5898 -> + IoError DeleteNoEntIoError + + 4362 -> + IoError CloseIoError + + 1290 -> + IoError DirFSyncIoError + + 1802 -> + IoError FStatIoError + + 1034 -> + IoError FSyncIoError + + 6410 -> + IoError GetTempPathIoError + + 3850 -> + IoError LockIoError + + 6154 -> + IoError MMapIoError + + 3082 -> + IoError NoMemIoError + + 2314 -> + IoError RdLockIoError + + 266 -> + IoError ReadIoError + + 7946 -> + IoError RollbackAtomicIoError + + 5642 -> + IoError SeekIoError + + 5130 -> + IoError ShmLockIoError + + 5386 -> + IoError ShmMapIoError + + 4618 -> + IoError ShmOpenIoError + + 4874 -> + IoError ShmSizeIoError + + 522 -> + IoError ShortReadIoError + + 1546 -> + IoError TruncateIoError + + 2058 -> + IoError UnlockIoError + + 6922 -> + IoError VNodeIoError + + 778 -> + IoError WriteIoError + + -- Locked errors + + 6 -> + LockedError (GenericLockedError message) + + 262 -> + LockedError SharedCacheLockedError + + 518 -> + LockedError VTabLockedError + + -- Mismatch error + + 20 -> + MismatchError + + -- Misuse error + + 21 -> + MisuseError + + -- No LFS error + + 22 -> + NoLfsError + + -- No memory error + + 7 -> + NoMemError + + -- Not a DB error + + 26 -> + NotADbError + + -- Not found error + + 12 -> + NotFoundError + + -- Notice errors + + 27 -> + NoticeError (GenericNoticeError message) + + 539 -> + NoticeError RecoverRollbackNoticeError + + 283 -> + NoticeError RecoverWalNoticeError + + -- Perm error + + 3 -> + PermError + + -- Protocol error + + 15 -> + ProtocolError + + -- Range error + + 25 -> + RangeError + + -- Read only errors + + 8 -> + ReadOnlyError (GenericReadOnlyError message) + + 1288 -> + ReadOnlyError CantInitReadOnlyError + + 520 -> + ReadOnlyError CantLockReadOnlyError + + 1032 -> + ReadOnlyError DbMovedReadOnlyError + + 1544 -> + ReadOnlyError DirectoryReadOnlyError + + 264 -> + ReadOnlyError RecoveryReadOnlyError + 776 -> + ReadOnlyError RollbackReadOnlyError -errorToString : Error -> String -errorToString error = - when error is - GenericError s -> - s + -- Schema error - NoResultsError -> - "Expected a result but got none." + 17 -> + SchemaError - MultipleResultsError n -> - "Expected one result but got " ++ String.fromInt n + -- Too big error - ForeignKeyError s -> - "Foreign key error: " ++ s + 18 -> + TooBigError - UniqueConstraintError s -> - "Unique constraint error: " ++ s + -- All other errors (unknown) - DecodingError e -> - "Error decoding results: " ++ Decode.errorToString e + _ -> + UnknownError message From ce2f3364f391175f3e55a48384c166e24e5b0f13 Mon Sep 17 00:00:00 2001 From: Joey Bright Date: Sat, 12 Sep 2026 12:44:56 -0700 Subject: [PATCH 2/7] Better error handling (not unknown) when a specific type of node error code is produced --- integration-tests/sqlite/src/Main.gren | 2 +- src/Gren/Kernel/Sqlite.js | 2 +- src/Sqlite.gren | 494 ++++++++++++------------- 3 files changed, 249 insertions(+), 249 deletions(-) diff --git a/integration-tests/sqlite/src/Main.gren b/integration-tests/sqlite/src/Main.gren index bf0de5a..c2cc4fc 100644 --- a/integration-tests/sqlite/src/Main.gren +++ b/integration-tests/sqlite/src/Main.gren @@ -69,7 +69,7 @@ tests fsPerm = Expect.fail "Failed for unknown reason" , awaitError "Too many templates" (execBadTemplate 3 db) <| \err -> test "Is invalid" <| \_ -> - Expect.equal (Sqlite.UnknownError "Unknown named parameter 'id1'") err + Expect.equal (Sqlite.Error "Unknown named parameter 'id1'") err , await "Closing the database" (Sqlite.close db) <| \_ -> test "Works" <| \_ -> Expect.pass diff --git a/src/Gren/Kernel/Sqlite.js b/src/Gren/Kernel/Sqlite.js index 57f35e3..773c979 100644 --- a/src/Gren/Kernel/Sqlite.js +++ b/src/Gren/Kernel/Sqlite.js @@ -255,5 +255,5 @@ var _Sqlite_executeScript = F2(function (script, db) { }); var _Sqlite_constructError = function (e) { - return __Scheduler_fail(A2(__Sqlite_errorCodeToError, e.errcode, e.message)); + return __Scheduler_fail(A3(__Sqlite_errorCodeToError, e.code, e.errcode, e.message)); }; diff --git a/src/Sqlite.gren b/src/Sqlite.gren index 4a7abfd..ed53043 100644 --- a/src/Sqlite.gren +++ b/src/Sqlite.gren @@ -226,7 +226,7 @@ type Error | CantOpenError CantOpenError | ConstraintError ConstraintError | CorruptError CorruptError - | Error GenericError + | Error String | IoError IoError | LockedError LockedError | MismatchError @@ -307,14 +307,6 @@ type CorruptError | VTabCorruptError -{-|-} -type GenericError - = GenericError String - | MissingCollSeqGenericError - | RetryGenericError - | SnapshotGenericError - - {-|-} type IoError = GenericIoError String @@ -379,351 +371,359 @@ type ReadOnlyError {-|-} -errorCodeToError : Int -> String -> Error -errorCodeToError errorCode message = - when errorCode is - -- Abort errors +errorCodeToError : String -> Int -> String -> Error +errorCodeToError errorType errorCode message = + when errorType is + "ERR_INVALID_STATE" -> + Error message - 4 -> - AbortError (GenericAbortError message) + "ERR_SQLITE_ERROR" -> + when errorCode is + -- Abort errors - 516 -> - AbortError RollbackAbortError + 4 -> + AbortError (GenericAbortError message) - -- Auth errors + 516 -> + AbortError RollbackAbortError - 23 -> - AuthError (GenericAuthError message) + -- Auth errors - 279 -> - AuthError UserAuthError + 23 -> + AuthError (GenericAuthError message) - -- Busy errors + 279 -> + AuthError UserAuthError - 5 -> - BusyError (GenericBusyError message) + -- Busy errors - 261 -> - BusyError RecoveryBusyError + 5 -> + BusyError (GenericBusyError message) - 517 -> - BusyError SnapshotBusyError + 261 -> + BusyError RecoveryBusyError - 773 -> - BusyError TimeoutBusyError + 517 -> + BusyError SnapshotBusyError - -- Can't open errors + 773 -> + BusyError TimeoutBusyError - 14 -> - CantOpenError (GenericCantOpenError message) + -- Can't open errors - 1038 -> - CantOpenError ConvPathCantOpenError + 14 -> + CantOpenError (GenericCantOpenError message) - 1294 -> - CantOpenError DirtyWalCantOpenError + 1038 -> + CantOpenError ConvPathCantOpenError - 782 -> - CantOpenError FullPathCantOpenError + 1294 -> + CantOpenError DirtyWalCantOpenError - 526 -> - CantOpenError IsDirCantOpenError + 782 -> + CantOpenError FullPathCantOpenError - 270 -> - CantOpenError NoTempDirCantOpenError + 526 -> + CantOpenError IsDirCantOpenError - 1550 -> - CantOpenError SymLinkCantOpenError + 270 -> + CantOpenError NoTempDirCantOpenError - -- Constraint errors + 1550 -> + CantOpenError SymLinkCantOpenError - 19 -> - ConstraintError (GenericConstraintError message) + -- Constraint errors - 275 -> - ConstraintError CheckConstraintError - - 531 -> - ConstraintError CommitHookConstraintError - - 3091 -> - ConstraintError DataTypeConstraintError + 19 -> + ConstraintError (GenericConstraintError message) - 787 -> - ConstraintError ForeignKeyConstraintError + 275 -> + ConstraintError CheckConstraintError + + 531 -> + ConstraintError CommitHookConstraintError + + 3091 -> + ConstraintError DataTypeConstraintError - 1043 -> - ConstraintError FunctionConstraintError + 787 -> + ConstraintError ForeignKeyConstraintError - 1299 -> - ConstraintError NotNullConstraintError + 1043 -> + ConstraintError FunctionConstraintError - 2835 -> - ConstraintError PrimaryKeyConstraintError + 1299 -> + ConstraintError NotNullConstraintError - 1555 -> - ConstraintError PrimaryKeyConstraintError - - 2579 -> - ConstraintError RowIdConstraintError + 2835 -> + ConstraintError PrimaryKeyConstraintError - 1811 -> - ConstraintError TriggerConstraintError + 1555 -> + ConstraintError PrimaryKeyConstraintError + + 2579 -> + ConstraintError RowIdConstraintError - 2067 -> - ConstraintError UniqueConstraintError - - 2323 -> - ConstraintError VTabConstraintError + 1811 -> + ConstraintError TriggerConstraintError - -- Corrupt errors + 2067 -> + ConstraintError UniqueConstraintError + + 2323 -> + ConstraintError VTabConstraintError - 11 -> - CorruptError (GenericCorruptError message) - - 779 -> - CorruptError IndexCorruptError - - 523 -> - CorruptError SequenceCorruptError + -- Corrupt errors - 267 -> - CorruptError VTabCorruptError + 11 -> + CorruptError (GenericCorruptError message) + + 779 -> + CorruptError IndexCorruptError + + 523 -> + CorruptError SequenceCorruptError - -- Error + 267 -> + CorruptError VTabCorruptError - 1 -> - Error (GenericError message) + -- Error - 257 -> - Error MissingCollSeqGenericError + 1 -> + Error message - 513 -> - Error RetryGenericError - - 769 -> - Error SnapshotGenericError + 257 -> + Error message - -- Full error + 513 -> + Error message + + 769 -> + Error message - 13 -> - FullError + -- Full error - -- Internal error + 13 -> + FullError - 2 -> - InternalError + -- Internal error - -- Interrupt Error + 2 -> + InternalError - 9 -> - InterruptError + -- Interrupt Error - -- IO errors + 9 -> + InterruptError - 10 -> - IoError (GenericIoError message) + -- IO errors - 3338 -> - IoError AccessIoError - - 7178 -> - IoError AuthIoError + 10 -> + IoError (GenericIoError message) - 7434 -> - IoError BeginAtomicIoError - - 2826 -> - IoError BlockedIoError + 3338 -> + IoError AccessIoError + + 7178 -> + IoError AuthIoError - 3594 -> - IoError CheckReservedLockIoError + 7434 -> + IoError BeginAtomicIoError + + 2826 -> + IoError BlockedIoError - 4106 -> - IoError CloseIoError + 3594 -> + IoError CheckReservedLockIoError - 7690 -> - IoError CommitAtomicIoError + 4106 -> + IoError CloseIoError - 6666 -> - IoError ConvPathIoError + 7690 -> + IoError CommitAtomicIoError - 8458 -> - IoError CorruptFsIoError + 6666 -> + IoError ConvPathIoError - 8202 -> - IoError DataIoError + 8458 -> + IoError CorruptFsIoError - 2570 -> - IoError DeleteIoError + 8202 -> + IoError DataIoError - 5898 -> - IoError DeleteNoEntIoError + 2570 -> + IoError DeleteIoError - 4362 -> - IoError CloseIoError + 5898 -> + IoError DeleteNoEntIoError - 1290 -> - IoError DirFSyncIoError + 4362 -> + IoError CloseIoError - 1802 -> - IoError FStatIoError + 1290 -> + IoError DirFSyncIoError - 1034 -> - IoError FSyncIoError + 1802 -> + IoError FStatIoError - 6410 -> - IoError GetTempPathIoError + 1034 -> + IoError FSyncIoError - 3850 -> - IoError LockIoError + 6410 -> + IoError GetTempPathIoError - 6154 -> - IoError MMapIoError + 3850 -> + IoError LockIoError - 3082 -> - IoError NoMemIoError - - 2314 -> - IoError RdLockIoError + 6154 -> + IoError MMapIoError - 266 -> - IoError ReadIoError + 3082 -> + IoError NoMemIoError + + 2314 -> + IoError RdLockIoError - 7946 -> - IoError RollbackAtomicIoError + 266 -> + IoError ReadIoError - 5642 -> - IoError SeekIoError + 7946 -> + IoError RollbackAtomicIoError - 5130 -> - IoError ShmLockIoError + 5642 -> + IoError SeekIoError - 5386 -> - IoError ShmMapIoError + 5130 -> + IoError ShmLockIoError - 4618 -> - IoError ShmOpenIoError + 5386 -> + IoError ShmMapIoError - 4874 -> - IoError ShmSizeIoError + 4618 -> + IoError ShmOpenIoError - 522 -> - IoError ShortReadIoError + 4874 -> + IoError ShmSizeIoError - 1546 -> - IoError TruncateIoError + 522 -> + IoError ShortReadIoError - 2058 -> - IoError UnlockIoError + 1546 -> + IoError TruncateIoError - 6922 -> - IoError VNodeIoError - - 778 -> - IoError WriteIoError + 2058 -> + IoError UnlockIoError - -- Locked errors + 6922 -> + IoError VNodeIoError + + 778 -> + IoError WriteIoError - 6 -> - LockedError (GenericLockedError message) + -- Locked errors - 262 -> - LockedError SharedCacheLockedError - - 518 -> - LockedError VTabLockedError + 6 -> + LockedError (GenericLockedError message) - -- Mismatch error + 262 -> + LockedError SharedCacheLockedError + + 518 -> + LockedError VTabLockedError - 20 -> - MismatchError + -- Mismatch error - -- Misuse error + 20 -> + MismatchError - 21 -> - MisuseError + -- Misuse error - -- No LFS error + 21 -> + MisuseError - 22 -> - NoLfsError + -- No LFS error - -- No memory error + 22 -> + NoLfsError - 7 -> - NoMemError + -- No memory error - -- Not a DB error + 7 -> + NoMemError - 26 -> - NotADbError + -- Not a DB error - -- Not found error + 26 -> + NotADbError - 12 -> - NotFoundError + -- Not found error - -- Notice errors + 12 -> + NotFoundError - 27 -> - NoticeError (GenericNoticeError message) + -- Notice errors - 539 -> - NoticeError RecoverRollbackNoticeError - - 283 -> - NoticeError RecoverWalNoticeError + 27 -> + NoticeError (GenericNoticeError message) - -- Perm error + 539 -> + NoticeError RecoverRollbackNoticeError + + 283 -> + NoticeError RecoverWalNoticeError - 3 -> - PermError + -- Perm error - -- Protocol error - - 15 -> - ProtocolError + 3 -> + PermError - -- Range error + -- Protocol error + + 15 -> + ProtocolError - 25 -> - RangeError + -- Range error - -- Read only errors + 25 -> + RangeError - 8 -> - ReadOnlyError (GenericReadOnlyError message) + -- Read only errors - 1288 -> - ReadOnlyError CantInitReadOnlyError + 8 -> + ReadOnlyError (GenericReadOnlyError message) - 520 -> - ReadOnlyError CantLockReadOnlyError - - 1032 -> - ReadOnlyError DbMovedReadOnlyError + 1288 -> + ReadOnlyError CantInitReadOnlyError - 1544 -> - ReadOnlyError DirectoryReadOnlyError + 520 -> + ReadOnlyError CantLockReadOnlyError + + 1032 -> + ReadOnlyError DbMovedReadOnlyError - 264 -> - ReadOnlyError RecoveryReadOnlyError + 1544 -> + ReadOnlyError DirectoryReadOnlyError - 776 -> - ReadOnlyError RollbackReadOnlyError + 264 -> + ReadOnlyError RecoveryReadOnlyError - -- Schema error + 776 -> + ReadOnlyError RollbackReadOnlyError - 17 -> - SchemaError + -- Schema error - -- Too big error + 17 -> + SchemaError - 18 -> - TooBigError + -- Too big error - -- All other errors (unknown) + 18 -> + TooBigError + -- All other errors (unknown) + + _ -> + UnknownError message + _ -> UnknownError message From 89e3e8767ba09f782273bfd55276f7378a9e7e6c Mon Sep 17 00:00:00 2001 From: Joey Bright Date: Sat, 12 Sep 2026 15:57:33 -0700 Subject: [PATCH 3/7] Ran `prettier` --- src/Gren/Kernel/Sqlite.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Gren/Kernel/Sqlite.js b/src/Gren/Kernel/Sqlite.js index 773c979..8fd06cf 100644 --- a/src/Gren/Kernel/Sqlite.js +++ b/src/Gren/Kernel/Sqlite.js @@ -255,5 +255,7 @@ var _Sqlite_executeScript = F2(function (script, db) { }); var _Sqlite_constructError = function (e) { - return __Scheduler_fail(A3(__Sqlite_errorCodeToError, e.code, e.errcode, e.message)); + return __Scheduler_fail( + A3(__Sqlite_errorCodeToError, e.code, e.errcode, e.message), + ); }; From 8598ace3069fac8ebf1ae84c7d53609af652b3a1 Mon Sep 17 00:00:00 2001 From: Joey Bright Date: Tue, 15 Sep 2026 20:26:35 -0700 Subject: [PATCH 4/7] Remove unused imports in kernel code --- src/Gren/Kernel/Sqlite.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gren/Kernel/Sqlite.js b/src/Gren/Kernel/Sqlite.js index 8fd06cf..0905fda 100644 --- a/src/Gren/Kernel/Sqlite.js +++ b/src/Gren/Kernel/Sqlite.js @@ -1,6 +1,6 @@ /* -import Sqlite exposing (errorCodeToError, GenericError, ForeignKeyError, UniqueConstraintError, DecodingError, MultipleResultsError) +import Sqlite exposing (errorCodeToError, DecodingError, MultipleResultsError) import Gren.Kernel.FilePath exposing (toString) import Gren.Kernel.Scheduler exposing (binding, succeed, fail) import Gren.Kernel.Json exposing (wrap, unwrap) From 2d1312474144d9c35d6073a66d09a8379cd4ee83 Mon Sep 17 00:00:00 2001 From: Joey Bright Date: Tue, 15 Sep 2026 20:34:12 -0700 Subject: [PATCH 5/7] Get rid of `UnknownError` in favor of `Error` in all unknown error cases --- src/Sqlite.gren | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Sqlite.gren b/src/Sqlite.gren index ed53043..4a49d7e 100644 --- a/src/Sqlite.gren +++ b/src/Sqlite.gren @@ -248,7 +248,6 @@ type Error | SchemaError | MultipleResultsError Int | DecodingError Decode.Error - | UnknownError String {-|-} @@ -723,7 +722,7 @@ errorCodeToError errorType errorCode message = -- All other errors (unknown) _ -> - UnknownError message + Error message _ -> - UnknownError message + Error message From 8aa271e711898d1d3a9235b5d17f4b687595046a Mon Sep 17 00:00:00 2001 From: Joey Bright Date: Tue, 15 Sep 2026 21:05:40 -0700 Subject: [PATCH 6/7] `errorToString` implementation --- src/Sqlite.gren | 300 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) diff --git a/src/Sqlite.gren b/src/Sqlite.gren index 4a49d7e..5612d9b 100644 --- a/src/Sqlite.gren +++ b/src/Sqlite.gren @@ -726,3 +726,303 @@ errorCodeToError errorType errorCode message = _ -> Error message + + +{-| Transform a given `Error` into a descriptive `String`. + +Each error string for known SQLite errors contain the error code found at https://sqlite.org/rescode.html. +More details on the errors can be found by their code on that page. +-} +errorToString : Error -> String +errorToString passedError = + when passedError is + AbortError (GenericAbortError string) -> + "(4) SQLite abort error: " ++ string + + AbortError RollbackAbortError -> + "(516) SQLite abort error: Transaction rolled back" + + AuthError (GenericAuthError string) -> + "(23) SQLite auth error: " ++ string + + AuthError UserAuthError -> + "(279) SQlite auth error: User lacks the proper authorization" + + BusyError (GenericBusyError string) -> + "(5) SQLite busy error: " ++ string + + BusyError RecoveryBusyError -> + "(261) SQLite busy error: Recovering WAL" + + BusyError SnapshotBusyError -> + "(517) SQLite busy error: Snapshot" + + BusyError TimeoutBusyError -> + "(773) SQLite busy error: Timeout " + + CantOpenError (GenericCantOpenError string) -> + "(14) SQLite can't open error: " ++ string + + CantOpenError ConvPathCantOpenError -> + "(1038) SQLite can't open error: Error with Cygwin VFS" + + CantOpenError DirtyWalCantOpenError -> + "(1294) SQLite can't open error: Error code not in use by SQLite at this time. Please report if you run into this!" + + CantOpenError FullPathCantOpenError -> + "(782) SQLite can't open error: Unable to convert the filename into a full pathname" + + CantOpenError IsDirCantOpenError -> + "(526) SQLite can't open error: File is actually a directory" + + CantOpenError NoTempDirCantOpenError -> + "(270) SQLite can't open error: Error code no longer in use. Please report if you run into this!" + + CantOpenError SymLinkCantOpenError -> + "(1550) SQLite can't open error: SQLITE_OPEN_NOFOLLOW flag is used and the database file is a symbolic link" + + ConstraintError (GenericConstraintError string) -> + "(19) SQLite constraint error: " ++ string + + ConstraintError CheckConstraintError -> + "(275) SQLite constraint error: CHECK constraint failed" + + ConstraintError CommitHookConstraintError -> + "(531) SQLite constraint error: Commit hook callback returned non-zero" + + ConstraintError DataTypeConstraintError -> + "(3091) SQLite constraint error: Incorrect value type inserted into column in STRICT table" + + ConstraintError ForeignKeyConstraintError -> + "(787) SQLite constraint error: Foreign key constraint failed" + + ConstraintError FunctionConstraintError -> + "(1043) SQLite constraint error: Error returned by extension function" + + ConstraintError NotNullConstraintError -> + "(1299) SQLite constraint error: NOT NULL constraint failed" + + ConstraintError PinnedConstraintError -> + "(2835) SQLite constraint error: UPDATE trigger attempted to delete the row that was being updated in the middle of the update" + + ConstraintError PrimaryKeyConstraintError -> + "(1555) SQLite constraint error: PRIMARY KEY constraint failed" + + ConstraintError RowIdConstraintError -> + "(2579) SQLite constraint error: rowid is not unique" + + ConstraintError TriggerConstraintError -> + "(1811) SQLite constraint error: RAISE function within a trigger fired, causing the SQL statement to abort" + + ConstraintError UniqueConstraintError -> + "(2067) SQLite constraint error: UNIQUE constraint failed" + + ConstraintError VTabConstraintError -> + "(2323) SQLite constraint error: Error with application-defined virtual table" + + CorruptError (GenericCorruptError string) -> + "(11) SQLite corrupt error: " ++ string + + CorruptError IndexCorruptError -> + "(779) SQLite corrupt error: Entry missing from index" + + CorruptError SequenceCorruptError -> + "(523) SQLite corrupt error: sqlite_sequence table schema corrupt" + + CorruptError VTabCorruptError -> + "(267) SQLite corrupt error: Virtual table corrupt" + + Error string -> + "Unknown or generic SQLite erorr: " ++ string + + IoError (GenericIoError string) -> + "(10) SQLite IO error: " ++ string + + IoError AccessIoError -> + "(3338) SQLite IO error: I/O error within the xAccess method on the sqlite3_vfs object" + + IoError AuthIoError -> + "(7178) SQLite IO error: SQLite extension error" + + IoError BeginAtomicIoError -> + "(7434) SQLite IO error: Begin atomic write error" + + IoError BlockedIoError -> + "(2826) SQLite IO error: Error code no longer used. Please report if you run into this!" + + IoError CheckReservedLockIoError -> + "(3594) SQLite IO error: xCheckReservedLock method" + + IoError CloseIoError -> + "(4106) SQLite IO error: xClose method" + + IoError CommitAtomicIoError -> + "(7690) SQLite IO error: Commit atomic write error" + + IoError ConvPathIoError -> + "(6666) SQLite IO error: cygwin_conv_path() system call failed" + + IoError CorruptFsIoError -> + "(8458) SQLite IO error: Corrupt filesystem" + + IoError DataIoError -> + "(8202) SQLite IO error: Database page checksum incorrect" + + IoError DeleteIoError -> + "(2570) SQLite IO error: xDelete method" + + IoError DeleteNoEntIoError -> + "(5898) SQLite IO error: File does not exist" + + IoError DirectoryCloseIoError -> + "(4362) SQLite IO error: Error code no longer used. Please report if you run into this!" + + IoError DirFSyncIoError -> + "(1290) SQLite IO error: VFS layer while trying to invoke fsync() on directory" + + IoError FStatIoError -> + "(1802) SQLite IO error: VFS layer while trying to invoke fstat()" + + IoError FSyncIoError -> + "(1034) SQLite IO error: VFS layer while trying to invoke fsync()" + + IoError GetTempPathIoError -> + "(6410) SQLite IO error: Cannot determine place to put temporary files" + + IoError LockIoError -> + "(3850) SQLite IO error: Advisory file locking logic" + + IoError MMapIoError -> + "(6154) SQLite IO error: xFetch or xUnfetch methods on the sqlite3_io_methods object" + + IoError NoMemIoError -> + "(3082) SQLite IO error: Insufficient memory" + + IoError RdLockIoError -> + "(2314) SQLite IO error: Locking file" + + IoError ReadIoError -> + "(266) SQLite IO error: Reading file from disk" + + IoError RollbackAtomicIoError -> + "(7946) SQLite IO error: Rollback atomic write error" + + IoError SeekIoError -> + "(5642) SQLite IO error: Problem while trying to seek a file descriptor to the beginning point of the file where the read or write is to occur" + + IoError ShmLockIoError -> + "(5130) SQLite IO error: Error code no longer used. Please report if you run into this!" + + IoError ShmMapIoError -> + "(5386) SQLite IO error: xShmMap method on the sqlite3_io_methods object" + + IoError ShmOpenIoError -> + "(4618) SQLite IO error: xShmMap method on the sqlite3_io_methods object while trying to open a new shared memory segment" + + IoError ShmSizeIoError -> + "(4874) SQLite IO error: Filesystem may be out of space" + + IoError ShortReadIoError -> + "(522) SQLite IO error: Bytes gotten does not equal bytes requested" + + IoError TruncateIoError -> + "(1546) SQLite IO error: Error trying to changes the size of a file" + + IoError UnlockIoError -> + "(2058) SQLite IO error: xUnlock method on the sqlite3_io_methods object" + + IoError VNodeIoError -> + "(6922) SQLite IO error: Error returned by extension" + + IoError WriteIoError -> + "(778) SQLite IO error: Writing file to disk" + + LockedError (GenericLockedError string) -> + "(6) SQLite locked error: " ++ string + + LockedError SharedCacheLockedError -> + "(262) SQLite locked error: Access blocked due to another database connecting using the same record" + + LockedError VTabLockedError -> + "(518) SQLite locked error: Virtual table extension locked by another operation" + + MismatchError -> + "(20) SQLite datatype mismatch error" + + MisuseError -> + "(21) SQLite misuse error" + + NoLfsError -> + "(22) SQLite no LFS error: File too large" + + NoMemError -> + "(7) SQLite no memory error: Unable to allocated necessary memory for operation" + + NotADbError -> + "(26) SQLite not a db error: The given file does not seem to be a SQLite database file" + + NotFoundError -> + "(12) SQLite not found error" + + NoticeError (GenericNoticeError string) -> + "(27) SQLite notice: " ++ string + + NoticeError RecoverRollbackNoticeError -> + "(539) SQLite notice: Hot journal rolled back" + + NoticeError RecoverWalNoticeError -> + "(283) SQLite notice: WAL mode database file recovered" + + PermError -> + "(3) SQLite perm error: Requested access mode for a newly created database could not be provided" + + ProtocolError -> + "(15) SQLite protocol error: Problem with file locking protocol" + + RangeError -> + "(25) SQLite range error" + + ReadOnlyError (GenericReadOnlyError string) -> + "(8) SQLite read error: " ++ string + + ReadOnlyError CantInitReadOnlyError -> + "(1288) SQLite read error: Shared memory issue" + + ReadOnlyError CantLockReadOnlyError -> + "(520) SQLite read error: Unable to obtain read lock for WAL" + + ReadOnlyError DbMovedReadOnlyError -> + "(1032) SQLite read error: Database file moved since it was opened" + + ReadOnlyError DirectoryReadOnlyError -> + "(1544) SQLite read error: Unable to create journal file in same directory as database" + + ReadOnlyError RecoveryReadOnlyError -> + "(264) SQLite read error: Database needs recovery but only has read, not write, access" + + ReadOnlyError RollbackReadOnlyError -> + "(776) SQLite read error: Cannot rollback hot journal due to database being read only" + + FullError -> + "(13) SQLite full error: Disk is full and cannot write anymore data to the database" + + InternalError -> + "(2) SQLite internal error: Malfunction with SQLite internals" + + InterruptError -> + "(9) SQLite interrupt error: Operation interrupted" + + TooBigError -> + "(18) SQLite too big error: String or blob larger than 1,000,000,000 bytes" + + NoResultsError -> + "No results returned for the given query" + + SchemaError -> + "(17) SQLite schema error: Database scheme changed" + + MultipleResultsError int -> + "Obtained multiple results when one was expected. Result count: " ++ (String.fromInt int) + + DecodingError error -> + "SQLite JSON decoding error: " ++ error From c12c17282f6922f7ad2ed4921f33d9d1b2b0788b Mon Sep 17 00:00:00 2001 From: Joey Bright Date: Thu, 17 Sep 2026 20:47:46 -0700 Subject: [PATCH 7/7] Update gren.json --- gren.json | 64 +++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/gren.json b/gren.json index 4a534d8..72a0bfc 100644 --- a/gren.json +++ b/gren.json @@ -1,34 +1,34 @@ { - "type": "package", - "platform": "node", - "name": "gren-lang/node", - "summary": "Run Gren on Node.js", - "license": "BSD-3-Clause", - "version": "6.1.3", - "exposed-modules": [ - "Node", - "Init", - "Terminal", - "ChildProcess", - "FileSystem", - "FileSystem.FileHandle", - "FileSystem.Path", - "HttpClient", - "HttpServer", - "HttpServer.Response", - "WebSocketServer", - "WebSocketServer.Connection", - "Sqlite", - "Sqlite.Decode", - "Sqlite.Decode.Row", - "Sqlite.Encode", - "Sqlite.Encode.Row", - "Sqlite.Function", - "Sqlite.Aggregate" - ], - "gren-version": "0.6.0 <= v < 0.7.0", - "dependencies": { - "gren-lang/core": "7.0.0 <= v < 8.0.0", - "gren-lang/url": "6.0.0 <= v < 7.0.0" - } + "type": "package", + "platform": "node", + "name": "gren-lang/node", + "summary": "Run Gren on Node.js", + "license": "BSD-3-Clause", + "version": "6.1.3", + "exposed-modules": [ + "Node", + "Init", + "Terminal", + "ChildProcess", + "FileSystem", + "FileSystem.FileHandle", + "FileSystem.Path", + "HttpClient", + "HttpServer", + "HttpServer.Response", + "WebSocketServer", + "WebSocketServer.Connection", + "Sqlite", + "Sqlite.Decode", + "Sqlite.Decode.Row", + "Sqlite.Encode", + "Sqlite.Encode.Row", + "Sqlite.Function", + "Sqlite.Aggregate" + ], + "gren-version": "0.6.0 <= v < 0.7.0", + "dependencies": { + "gren-lang/core": "7.0.0 <= v < 8.0.0", + "gren-lang/url": "6.0.0 <= v < 7.0.0" + } }