-module(cquill@error). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/cquill/error.gleam"). -export([is_not_found/1, is_constraint_violation/1, is_unique_violation/1, is_foreign_key_violation/1, is_connection_error/1, is_recoverable/1, is_query_error/1, format_error/1, format_error_compact/1, format_transaction_error/1, format_transaction_error_compact/1, format_savepoint_error/1, format_savepoint_error_compact/1, from_postgres_error/3, from_mysql_error/2, from_sqlite_error/2, not_found/0, query_failed/1, query_failed_with_code/2, connection_failed/1, timeout/0, unique_violation/2, not_supported/1, adapter_specific/2]). -export_type([adapter_error/0, transaction_error/1, savepoint_error/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -type adapter_error() :: not_found | {too_many_rows, integer(), integer()} | {connection_failed, binary()} | connection_timeout | pool_exhausted | {connection_lost, binary()} | {query_failed, binary(), gleam@option:option(binary())} | {decode_failed, integer(), binary(), binary(), binary()} | timeout | {unique_violation, binary(), binary()} | {foreign_key_violation, binary(), binary()} | {check_violation, binary(), binary()} | {not_null_violation, binary()} | {constraint_violation, binary(), binary()} | {stale_data, binary(), binary()} | {data_integrity_error, binary()} | {not_supported, binary()} | {adapter_specific, binary(), binary()}. -type transaction_error(LAT) :: {user_error, LAT} | {adapter_transaction_error, adapter_error()} | {begin_failed, binary()} | {commit_failed, binary()} | rolled_back | {transaction_rollback, binary()} | transaction_connection_lost | nested_transaction_error | transaction_timeout | serialization_failure. -type savepoint_error(LAU) :: {savepoint_not_found, binary()} | {savepoint_adapter_error, adapter_error()} | {savepoint_user_error, LAU} | {savepoint_creation_failed, binary()} | {savepoint_release_failed, binary()} | savepoint_no_transaction. -file("src/cquill/error.gleam", 169). ?DOC(" Check if an error indicates the record was not found\n"). -spec is_not_found(adapter_error()) -> boolean(). is_not_found(Error) -> case Error of not_found -> true; _ -> false end. -file("src/cquill/error.gleam", 177). ?DOC(" Check if an error is any kind of constraint violation\n"). -spec is_constraint_violation(adapter_error()) -> boolean(). is_constraint_violation(Error) -> case Error of {unique_violation, _, _} -> true; {foreign_key_violation, _, _} -> true; {check_violation, _, _} -> true; {not_null_violation, _} -> true; {constraint_violation, _, _} -> true; _ -> false end. -file("src/cquill/error.gleam", 189). ?DOC(" Check if an error is a unique constraint violation\n"). -spec is_unique_violation(adapter_error()) -> boolean(). is_unique_violation(Error) -> case Error of {unique_violation, _, _} -> true; _ -> false end. -file("src/cquill/error.gleam", 197). ?DOC(" Check if an error is a foreign key violation\n"). -spec is_foreign_key_violation(adapter_error()) -> boolean(). is_foreign_key_violation(Error) -> case Error of {foreign_key_violation, _, _} -> true; _ -> false end. -file("src/cquill/error.gleam", 205). ?DOC(" Check if an error is a connection-related error\n"). -spec is_connection_error(adapter_error()) -> boolean(). is_connection_error(Error) -> case Error of {connection_failed, _} -> true; connection_timeout -> true; pool_exhausted -> true; {connection_lost, _} -> true; _ -> false end. -file("src/cquill/error.gleam", 216). ?DOC(" Check if an error is recoverable (can retry)\n"). -spec is_recoverable(adapter_error()) -> boolean(). is_recoverable(Error) -> case Error of {connection_failed, _} -> true; connection_timeout -> true; pool_exhausted -> true; {connection_lost, _} -> true; timeout -> true; {stale_data, _, _} -> true; _ -> false end. -file("src/cquill/error.gleam", 233). ?DOC(" Check if an error is a query/execution error\n"). -spec is_query_error(adapter_error()) -> boolean(). is_query_error(Error) -> case Error of {query_failed, _, _} -> true; {decode_failed, _, _, _, _} -> true; timeout -> true; _ -> false end. -file("src/cquill/error.gleam", 409). ?DOC( " Sanitize connection messages to prevent leaking sensitive information.\n" "\n" " Removes potential passwords, connection strings, and other secrets.\n" ). -spec sanitize_connection_message(binary()) -> binary(). sanitize_connection_message(Message) -> Lower = string:lowercase(Message), case ((((gleam_stdlib:contains_string(Lower, <<"password"/utf8>>) orelse gleam_stdlib:contains_string( Lower, <<"pwd="/utf8>> )) orelse gleam_stdlib:contains_string(Lower, <<"postgres://"/utf8>>)) orelse gleam_stdlib:contains_string(Lower, <<"mysql://"/utf8>>)) orelse gleam_stdlib:contains_string(Lower, <<"secret"/utf8>>)) orelse gleam_stdlib:contains_string(Lower, <<"api_key"/utf8>>) of true -> <<"[connection details redacted]"/utf8>>; false -> Message end. -file("src/cquill/error.gleam", 255). ?DOC( " Format an error for display with clear, actionable messages.\n" "\n" " ## Example\n" "\n" " ```gleam\n" " let error = UniqueViolation(\"users_email_key\", \"Key (email)=(test@example.com) already exists\")\n" " format_error(error)\n" " // -> \"Unique constraint violation on users_email_key\\n Key (email)=(test@example.com) already exists\\n\\nHint: Check if a record with this value exists before inserting,\\n or use an upsert operation for insert-or-update semantics.\"\n" " ```\n" ). -spec format_error(adapter_error()) -> binary(). format_error(Error) -> case Error of not_found -> <<"Record not found\n\nHint: Verify the record exists before querying, or use get_by which returns Option."/utf8>>; {too_many_rows, Expected, Got} -> <<<<<<<<"Too many rows returned: expected "/utf8, (erlang:integer_to_binary(Expected))/binary>>/binary, ", got "/utf8>>/binary, (erlang:integer_to_binary(Got))/binary>>/binary, "\n\nHint: Add more specific conditions to your query, or use get_all instead of get_one."/utf8>>; {connection_failed, Reason} -> <<<<"Connection failed: "/utf8, (sanitize_connection_message(Reason))/binary>>/binary, "\n\nHint: Check that the database server is running and accessible."/utf8>>; connection_timeout -> <<"Connection timed out\n\nHint: The database server may be overloaded or unreachable. Check network connectivity and server status."/utf8>>; pool_exhausted -> <<"Connection pool exhausted: all connections are in use\n\nHint: Increase the pool size, reduce long-running queries, or check for connection leaks."/utf8>>; {connection_lost, Reason@1} -> <<<<"Connection lost: "/utf8, (sanitize_connection_message(Reason@1))/binary>>/binary, "\n\nHint: The database connection was interrupted. This operation can be retried."/utf8>>; {query_failed, Message, none} -> <<"Query failed: "/utf8, Message/binary>>; {query_failed, Message@1, {some, Code}} -> <<<<<<"Query failed ["/utf8, Code/binary>>/binary, "]: "/utf8>>/binary, Message@1/binary>>; {decode_failed, Row, Column, Expected@1, Got@1} -> <<<<<<<<<<<<<<<<"Decode failed at row "/utf8, (erlang:integer_to_binary(Row))/binary>>/binary, ", column '"/utf8>>/binary, Column/binary>>/binary, "': expected type "/utf8>>/binary, Expected@1/binary>>/binary, ", got "/utf8>>/binary, Got@1/binary>>/binary, "\n\nHint: Check that the column type in your schema matches the database column type."/utf8>>; timeout -> <<"Operation timed out\n\nHint: Consider adding an index, optimizing the query, or increasing the timeout limit."/utf8>>; {unique_violation, Constraint, Detail} -> <<<<<<<<"Unique constraint violation on "/utf8, Constraint/binary>>/binary, "\n "/utf8>>/binary, Detail/binary>>/binary, "\n\nHint: Check if a record with this value exists before inserting,\n or use an upsert operation for insert-or-update semantics."/utf8>>; {foreign_key_violation, Constraint@1, Detail@1} -> <<<<<<<<"Foreign key violation on "/utf8, Constraint@1/binary>>/binary, "\n "/utf8>>/binary, Detail@1/binary>>/binary, "\n\nHint: Ensure the referenced record exists before creating this record,\n or check that you're not deleting a record that others depend on."/utf8>>; {check_violation, Constraint@2, Detail@2} -> <<<<<<<<"Check constraint violation on "/utf8, Constraint@2/binary>>/binary, "\n "/utf8>>/binary, Detail@2/binary>>/binary, "\n\nHint: Verify that the value meets the constraint requirements defined in the database."/utf8>>; {not_null_violation, Column@1} -> <<<<"NOT NULL violation on column '"/utf8, Column@1/binary>>/binary, "'\n\nHint: Provide a value for this required field, or update the schema to allow NULL."/utf8>>; {constraint_violation, Constraint@3, Detail@3} -> <<<<<<"Constraint violation on "/utf8, Constraint@3/binary>>/binary, "\n "/utf8>>/binary, Detail@3/binary>>; {stale_data, Expected@2, Actual} -> <<<<<<<<"Stale data detected: expected version "/utf8, Expected@2/binary>>/binary, ", found version "/utf8>>/binary, Actual/binary>>/binary, "\n\nHint: The record was modified by another process. Reload the data and retry your operation."/utf8>>; {data_integrity_error, Message@2} -> <<<<"Data integrity error: "/utf8, Message@2/binary>>/binary, "\n\nHint: Check that your data meets all schema requirements and constraints."/utf8>>; {not_supported, Operation} -> <<<<"Operation not supported: "/utf8, Operation/binary>>/binary, "\n\nHint: This operation is not available with the current adapter."/utf8>>; {adapter_specific, Code@1, Message@3} -> <<<<<<"Adapter error ["/utf8, Code@1/binary>>/binary, "]: "/utf8>>/binary, Message@3/binary>> end. -file("src/cquill/error.gleam", 355). ?DOC( " Format an error for display without hints (compact format).\n" "\n" " Use this for logging or when hints are not needed.\n" ). -spec format_error_compact(adapter_error()) -> binary(). format_error_compact(Error) -> case Error of not_found -> <<"Record not found"/utf8>>; {too_many_rows, Expected, Got} -> <<<<<<"Too many rows: expected "/utf8, (erlang:integer_to_binary(Expected))/binary>>/binary, ", got "/utf8>>/binary, (erlang:integer_to_binary(Got))/binary>>; {connection_failed, Reason} -> <<"Connection failed: "/utf8, (sanitize_connection_message(Reason))/binary>>; connection_timeout -> <<"Connection timed out"/utf8>>; pool_exhausted -> <<"Connection pool exhausted"/utf8>>; {connection_lost, Reason@1} -> <<"Connection lost: "/utf8, (sanitize_connection_message(Reason@1))/binary>>; {query_failed, Message, none} -> <<"Query failed: "/utf8, Message/binary>>; {query_failed, Message@1, {some, Code}} -> <<<<<<"Query failed ["/utf8, Code/binary>>/binary, "]: "/utf8>>/binary, Message@1/binary>>; {decode_failed, Row, Column, Expected@1, Got@1} -> <<<<<<<<<<<<<<"Decode failed at row "/utf8, (erlang:integer_to_binary(Row))/binary>>/binary, ", column '"/utf8>>/binary, Column/binary>>/binary, "': expected "/utf8>>/binary, Expected@1/binary>>/binary, ", got "/utf8>>/binary, Got@1/binary>>; timeout -> <<"Operation timed out"/utf8>>; {unique_violation, Constraint, Detail} -> <<<<<<"Unique constraint violation: "/utf8, Constraint/binary>>/binary, " - "/utf8>>/binary, Detail/binary>>; {foreign_key_violation, Constraint@1, Detail@1} -> <<<<<<"Foreign key violation: "/utf8, Constraint@1/binary>>/binary, " - "/utf8>>/binary, Detail@1/binary>>; {check_violation, Constraint@2, Detail@2} -> <<<<<<"Check constraint violation: "/utf8, Constraint@2/binary>>/binary, " - "/utf8>>/binary, Detail@2/binary>>; {not_null_violation, Column@1} -> <<"NOT NULL violation on column: "/utf8, Column@1/binary>>; {constraint_violation, Constraint@3, Detail@3} -> <<<<<<"Constraint violation: "/utf8, Constraint@3/binary>>/binary, " - "/utf8>>/binary, Detail@3/binary>>; {stale_data, Expected@2, Actual} -> <<<<<<"Stale data: expected version "/utf8, Expected@2/binary>>/binary, ", found "/utf8>>/binary, Actual/binary>>; {data_integrity_error, Message@2} -> <<"Data integrity error: "/utf8, Message@2/binary>>; {not_supported, Operation} -> <<"Operation not supported: "/utf8, Operation/binary>>; {adapter_specific, Code@1, Message@3} -> <<<<<<"Adapter error ["/utf8, Code@1/binary>>/binary, "]: "/utf8>>/binary, Message@3/binary>> end. -file("src/cquill/error.gleam", 426). ?DOC(" Format a transaction error for display with actionable hints.\n"). -spec format_transaction_error(transaction_error(any())) -> binary(). format_transaction_error(Error) -> case Error of {user_error, _} -> <<"Transaction aborted: user error\n\nHint: Your transaction callback returned an error. The transaction has been rolled back."/utf8>>; {adapter_transaction_error, Adapter_err} -> <<"Transaction aborted: "/utf8, (format_error_compact(Adapter_err))/binary>>; {begin_failed, Reason} -> <<<<"Failed to begin transaction: "/utf8, Reason/binary>>/binary, "\n\nHint: Check database connection and permissions."/utf8>>; {commit_failed, Reason@1} -> <<<<"Failed to commit transaction: "/utf8, Reason@1/binary>>/binary, "\n\nHint: The transaction may have been rolled back. Check for constraint violations or connection issues."/utf8>>; rolled_back -> <<"Transaction was rolled back\n\nHint: An explicit rollback was requested during the transaction."/utf8>>; {transaction_rollback, Reason@2} -> <<<<"Transaction rolled back: "/utf8, Reason@2/binary>>/binary, "\n\nHint: The transaction was explicitly rolled back with the reason above."/utf8>>; transaction_connection_lost -> <<"Connection lost during transaction\n\nHint: The database connection was interrupted. The transaction state is unknown - verify data integrity."/utf8>>; nested_transaction_error -> <<"Nested transactions are not supported\n\nHint: Use savepoints for partial rollback within a transaction instead."/utf8>>; transaction_timeout -> <<"Transaction timed out\n\nHint: Consider breaking up long transactions or increasing the timeout limit."/utf8>>; serialization_failure -> <<"Serialization failure: concurrent transaction conflict\n\nHint: This operation can be safely retried. Another transaction modified the same data."/utf8>> end. -file("src/cquill/error.gleam", 467). ?DOC(" Format a transaction error without hints (compact format).\n"). -spec format_transaction_error_compact(transaction_error(any())) -> binary(). format_transaction_error_compact(Error) -> case Error of {user_error, _} -> <<"Transaction aborted: user error"/utf8>>; {adapter_transaction_error, Adapter_err} -> <<"Transaction aborted: "/utf8, (format_error_compact(Adapter_err))/binary>>; {begin_failed, Reason} -> <<"Failed to begin transaction: "/utf8, Reason/binary>>; {commit_failed, Reason@1} -> <<"Failed to commit transaction: "/utf8, Reason@1/binary>>; rolled_back -> <<"Transaction was rolled back"/utf8>>; {transaction_rollback, Reason@2} -> <<"Transaction rolled back: "/utf8, Reason@2/binary>>; transaction_connection_lost -> <<"Connection lost during transaction"/utf8>>; nested_transaction_error -> <<"Nested transactions are not supported"/utf8>>; transaction_timeout -> <<"Transaction timed out"/utf8>>; serialization_failure -> <<"Serialization failure: concurrent transaction conflict"/utf8>> end. -file("src/cquill/error.gleam", 485). ?DOC(" Format a savepoint error for display with actionable hints.\n"). -spec format_savepoint_error(savepoint_error(any())) -> binary(). format_savepoint_error(Error) -> case Error of {savepoint_not_found, Name} -> <<<<"Savepoint not found: '"/utf8, Name/binary>>/binary, "'\n\nHint: Verify the savepoint name and that it was created in the current transaction."/utf8>>; {savepoint_adapter_error, Adapter_err} -> <<"Savepoint operation failed: "/utf8, (format_error_compact(Adapter_err))/binary>>; {savepoint_user_error, _} -> <<"Savepoint aborted: user error\n\nHint: The savepoint callback returned an error. The savepoint has been rolled back."/utf8>>; {savepoint_creation_failed, Reason} -> <<<<"Failed to create savepoint: "/utf8, Reason/binary>>/binary, "\n\nHint: Check that you are within an active transaction."/utf8>>; {savepoint_release_failed, Reason@1} -> <<<<"Failed to release savepoint: "/utf8, Reason@1/binary>>/binary, "\n\nHint: The savepoint may have already been released or rolled back."/utf8>>; savepoint_no_transaction -> <<"Cannot use savepoint outside of a transaction\n\nHint: Savepoints must be created within an active transaction. Use repo.transaction first."/utf8>> end. -file("src/cquill/error.gleam", 514). ?DOC(" Format a savepoint error without hints (compact format).\n"). -spec format_savepoint_error_compact(savepoint_error(any())) -> binary(). format_savepoint_error_compact(Error) -> case Error of {savepoint_not_found, Name} -> <<"Savepoint not found: "/utf8, Name/binary>>; {savepoint_adapter_error, Adapter_err} -> <<"Savepoint operation failed: "/utf8, (format_error_compact(Adapter_err))/binary>>; {savepoint_user_error, _} -> <<"Savepoint aborted: user error"/utf8>>; {savepoint_creation_failed, Reason} -> <<"Failed to create savepoint: "/utf8, Reason/binary>>; {savepoint_release_failed, Reason@1} -> <<"Failed to release savepoint: "/utf8, Reason@1/binary>>; savepoint_no_transaction -> <<"Cannot use savepoint outside of a transaction"/utf8>> end. -file("src/cquill/error.gleam", 694). ?DOC(" Extract constraint name from error detail/message\n"). -spec extract_constraint_name(binary()) -> binary(). extract_constraint_name(Text) -> case gleam@string:split(Text, <<"constraint \""/utf8>>) of [_, Rest] -> case gleam@string:split(Rest, <<"\""/utf8>>) of [Name | _] -> Name; _ -> <<"unknown"/utf8>> end; _ -> case gleam@string:split(Text, <<"for key '"/utf8>>) of [_, Rest@1] -> case gleam@string:split(Rest@1, <<"'"/utf8>>) of [Name@1 | _] -> Name@1; _ -> <<"unknown"/utf8>> end; _ -> <<"unknown"/utf8>> end end. -file("src/cquill/error.gleam", 718). ?DOC(" Extract column name from error message\n"). -spec extract_column_name(binary()) -> binary(). extract_column_name(Text) -> case gleam@string:split(Text, <<"column \""/utf8>>) of [_, Rest] -> case gleam@string:split(Rest, <<"\""/utf8>>) of [Name | _] -> Name; _ -> <<"unknown"/utf8>> end; _ -> case gleam@string:split(Text, <<"Field '"/utf8>>) of [_, Rest@1] -> case gleam@string:split(Rest@1, <<"'"/utf8>>) of [Name@1 | _] -> Name@1; _ -> <<"unknown"/utf8>> end; _ -> <<"unknown"/utf8>> end end. -file("src/cquill/error.gleam", 548). ?DOC( " Map a PostgreSQL error code to an AdapterError.\n" "\n" " PostgreSQL error codes are 5-character strings where the first two\n" " characters indicate the error class. See:\n" " https://www.postgresql.org/docs/current/errcodes-appendix.html\n" "\n" " Common codes:\n" " - 23505: unique_violation\n" " - 23503: foreign_key_violation\n" " - 23514: check_violation\n" " - 23502: not_null_violation\n" " - 23000: integrity_constraint_violation\n" " - 08000: connection_exception\n" " - 08003: connection_does_not_exist\n" " - 08006: connection_failure\n" " - 57P01: admin_shutdown\n" " - 42P01: undefined_table\n" " - 42703: undefined_column\n" ). -spec from_postgres_error(binary(), binary(), binary()) -> adapter_error(). from_postgres_error(Code, Message, Detail) -> case Code of <<"23505"/utf8>> -> {unique_violation, extract_constraint_name(Detail), Detail}; <<"23503"/utf8>> -> {foreign_key_violation, extract_constraint_name(Detail), Detail}; <<"23514"/utf8>> -> {check_violation, extract_constraint_name(Detail), Detail}; <<"23502"/utf8>> -> {not_null_violation, extract_column_name(Message)}; <<"23000"/utf8>> -> {constraint_violation, extract_constraint_name(Detail), Detail}; <<"08000"/utf8>> -> {connection_failed, Message}; <<"08003"/utf8>> -> {connection_lost, <<"Connection does not exist"/utf8>>}; <<"08006"/utf8>> -> {connection_failed, <<"Connection failure: "/utf8, Message/binary>>}; <<"57P01"/utf8>> -> {connection_lost, <<"Server shutdown"/utf8>>}; <<"57P02"/utf8>> -> {connection_lost, <<"Crash shutdown"/utf8>>}; <<"57P03"/utf8>> -> {connection_failed, <<"Cannot connect now"/utf8>>}; <<"3D000"/utf8>> -> {query_failed, Message, {some, Code}}; <<"3F000"/utf8>> -> {query_failed, Message, {some, Code}}; <<"42P01"/utf8>> -> {query_failed, <<"Undefined table: "/utf8, Message/binary>>, {some, Code}}; <<"42703"/utf8>> -> {query_failed, <<"Undefined column: "/utf8, Message/binary>>, {some, Code}}; <<"42601"/utf8>> -> {query_failed, <<"Syntax error: "/utf8, Message/binary>>, {some, Code}}; <<"42501"/utf8>> -> {query_failed, <<"Insufficient privilege: "/utf8, Message/binary>>, {some, Code}}; <<"57014"/utf8>> -> timeout; <<"53300"/utf8>> -> pool_exhausted; <<"53400"/utf8>> -> {query_failed, <<"Configuration limit exceeded: "/utf8, Message/binary>>, {some, Code}}; _ -> {adapter_specific, Code, Message} end. -file("src/cquill/error.gleam", 607). ?DOC( " Map a MySQL error code to an AdapterError.\n" "\n" " Common MySQL error codes:\n" " - 1062: Duplicate entry (unique violation)\n" " - 1452: Foreign key constraint fails\n" " - 1364: No default value (not null violation)\n" " - 1048: Column cannot be null\n" " - 2002: Connection refused\n" " - 2003: Can't connect to server\n" " - 2006: Server has gone away\n" " - 2013: Lost connection during query\n" ). -spec from_mysql_error(integer(), binary()) -> adapter_error(). from_mysql_error(Code, Message) -> case Code of 1062 -> {unique_violation, extract_constraint_name(Message), Message}; 1452 -> {foreign_key_violation, extract_constraint_name(Message), Message}; 1364 -> {not_null_violation, extract_column_name(Message)}; 1048 -> {not_null_violation, extract_column_name(Message)}; 3819 -> {check_violation, extract_constraint_name(Message), Message}; 2002 -> {connection_failed, <<"Connection refused"/utf8>>}; 2003 -> {connection_failed, <<"Can't connect to server"/utf8>>}; 2006 -> {connection_lost, <<"Server has gone away"/utf8>>}; 2013 -> {connection_lost, <<"Lost connection during query"/utf8>>}; 1064 -> {query_failed, <<"Syntax error: "/utf8, Message/binary>>, {some, erlang:integer_to_binary(Code)}}; 1146 -> {query_failed, <<"Table doesn't exist: "/utf8, Message/binary>>, {some, erlang:integer_to_binary(Code)}}; 1054 -> {query_failed, <<"Unknown column: "/utf8, Message/binary>>, {some, erlang:integer_to_binary(Code)}}; _ -> {adapter_specific, erlang:integer_to_binary(Code), Message} end. -file("src/cquill/error.gleam", 669). ?DOC( " Classify a SQLite constraint violation based on the error message.\n" "\n" " SQLite's SQLITE_CONSTRAINT error (code 19) requires parsing the error\n" " message to determine the specific constraint type. This function uses\n" " a declarative approach with a list of patterns for better readability.\n" ). -spec classify_sqlite_constraint(binary()) -> adapter_error(). classify_sqlite_constraint(Message) -> Lower_message = string:lowercase(Message), Constraint_patterns = [{<<"unique"/utf8>>, fun(Msg) -> {unique_violation, extract_constraint_name(Msg), Msg} end}, {<<"foreign key"/utf8>>, fun(Msg@1) -> {foreign_key_violation, extract_constraint_name(Msg@1), Msg@1} end}, {<<"not null"/utf8>>, fun(Msg@2) -> {not_null_violation, extract_column_name(Msg@2)} end}, {<<"check"/utf8>>, fun(Msg@3) -> {check_violation, extract_constraint_name(Msg@3), Msg@3} end}], _pipe = Constraint_patterns, _pipe@1 = gleam@list:find( _pipe, fun(Pattern) -> gleam_stdlib:contains_string( Lower_message, erlang:element(1, Pattern) ) end ), _pipe@2 = gleam@result:map( _pipe@1, fun(Pattern@1) -> (erlang:element(2, Pattern@1))(Message) end ), gleam@result:unwrap( _pipe@2, {constraint_violation, <<"unknown"/utf8>>, Message} ). -file("src/cquill/error.gleam", 638). ?DOC( " Map a SQLite error code to an AdapterError.\n" "\n" " SQLite uses integer result codes. Extended result codes provide more detail.\n" " See: https://www.sqlite.org/rescode.html\n" ). -spec from_sqlite_error(integer(), binary()) -> adapter_error(). from_sqlite_error(Code, Message) -> case Code of 19 -> classify_sqlite_constraint(Message); 5 -> {connection_failed, <<"Database is locked"/utf8>>}; 6 -> {connection_failed, <<"Table is locked"/utf8>>}; 26 -> {connection_failed, <<"Not a database file"/utf8>>}; 1 -> {query_failed, Message, {some, erlang:integer_to_binary(Code)}}; _ -> {adapter_specific, erlang:integer_to_binary(Code), Message} end. -file("src/cquill/error.gleam", 745). ?DOC(" Create a NotFound error\n"). -spec not_found() -> adapter_error(). not_found() -> not_found. -file("src/cquill/error.gleam", 750). ?DOC(" Create a QueryFailed error\n"). -spec query_failed(binary()) -> adapter_error(). query_failed(Message) -> {query_failed, Message, none}. -file("src/cquill/error.gleam", 755). ?DOC(" Create a QueryFailed error with code\n"). -spec query_failed_with_code(binary(), binary()) -> adapter_error(). query_failed_with_code(Message, Code) -> {query_failed, Message, {some, Code}}. -file("src/cquill/error.gleam", 760). ?DOC(" Create a ConnectionFailed error\n"). -spec connection_failed(binary()) -> adapter_error(). connection_failed(Reason) -> {connection_failed, Reason}. -file("src/cquill/error.gleam", 765). ?DOC(" Create a Timeout error\n"). -spec timeout() -> adapter_error(). timeout() -> timeout. -file("src/cquill/error.gleam", 770). ?DOC(" Create a UniqueViolation error\n"). -spec unique_violation(binary(), binary()) -> adapter_error(). unique_violation(Constraint, Detail) -> {unique_violation, Constraint, Detail}. -file("src/cquill/error.gleam", 775). ?DOC(" Create a NotSupported error\n"). -spec not_supported(binary()) -> adapter_error(). not_supported(Operation) -> {not_supported, Operation}. -file("src/cquill/error.gleam", 780). ?DOC(" Create an AdapterSpecific error\n"). -spec adapter_specific(binary(), binary()) -> adapter_error(). adapter_specific(Code, Message) -> {adapter_specific, Code, Message}.