# ARX error codes (MySQL)

Every error an ARX call throws is an `ArxException` with a stable `Code` (`ArxErrorCode`), the same in every provider (a misuse found while the schema catalog is built at startup, such as a table declared twice, is an `ArgumentException`). The message starts with it (`ARX3001 UniqueViolation: …`) and the thousands digit is its `Category`. Catch by code, on the base class: `catch (ArxException e) when (e.Code == ArxErrorCode.RecordNotFound)`. Some codes come as a subclass (`ArxValidationException` before the database, `ArxDatabaseException` from it, `ArxNotSupportedException` for ARX8001), but not every one: a record not found (ARX2002) can be the base class, so a catch of a subclass can miss it. Retry only when `IsTransient` is true. The database's own error stays on the exception: `NativeCode`, and the driver's exception as `InnerException`.

## ARX1xxx Validation

ARX refused the call before sending it: invalid input, a misused connection, transaction or batch scope, or a name that looks like SQL injection.

| Code | Name | Meaning | Safe to retry | From MySQL |
|---|---|---|---|---|
| ARX1001 | `InvalidArgument` | Invalid input not covered by a more specific code. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1002 | `MissingEntityName` | The entity name is null or blank. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1003 | `InvalidIdentifier` | An entity or attribute name fails the identifier rules. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1004 | `DuplicateAttribute` | The same attribute appears more than once (names are case-insensitive). | no | no database error maps to it (ARX itself can still raise it) |
| ARX1005 | `InvalidLookup` | A lookup (`ArxEntityReference`) has no usable Id. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1006 | `InvalidSelectionSet` | A selection set value has no option set name. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1007 | `UnsupportedValueType` | An attribute value has a type the provider can't write. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1008 | `InvalidConnection` | The connection or transaction is of the wrong driver type, or the service has no connection string. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1009 | `TransactionMismatch` | The transaction belongs to a different connection. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1010 | `TransactionCompleted` | The transaction has already been committed, rolled back or disposed. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1011 | `SelectionSetValueNotAllowed` | A selection set value isn't allowed by its set in the catalog: not one of its options, of the wrong kind, a retired option, several values for a single-choice set, a duplicate, or a value the set's storage can't hold. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1012 | `UnknownSelectionSet` | A selection set value names a set that isn't in the catalog, or no catalog was supplied. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1013 | `InvalidDateTimeValue` | A date or time value that would be stored as something else than the caller meant: default(DateTime), default(DateTimeOffset) or default(DateOnly) (no real date: a database would store a sentinel or refuse it), or an array mixing UTC and Unspecified DateTime values. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1014 | `BatchScopeBusy` | A batch scope was called while another call on it was still running. A scope holds one connection, which runs one command at a time: await each call before the next. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1015 | `TransactionAborted` | A call or a commit on a transaction that an earlier failed call has aborted. The database has already discarded the transaction's work; it can only be rolled back. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1016 | `IdNotDeclared` | The entity's table isn't declared in the service's schema catalog, and the entity doesn't declare its own id column. A service with a catalog uses only what is declared: ARX doesn't guess an id column. A service created without a catalog reads the table's primary key instead (where the provider can), and raises `TableNotResolvable` when it can't. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1017 | `SuspectedInjection` | A name (entity, attribute, match column or type) contains SQL syntax: a quote, a statement separator, a comment marker, a bracket, an operator or an SQL keyword after a space. That is the shape of an SQL injection attempt, not of a typo, so it gets its own code to alert on. Refused before the database: nothing was sent. Values are never checked for this: they are always parameters, and any text is stored as typed. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1018 | `NotPreloaded` | The service is `Strict` and the call names a table or column that wasn't preloaded: refused before the database. Preload it, or turn Strict off. | no | no database error maps to it (ARX itself can still raise it) |
| ARX1019 | `TableNotResolvable` | A service without a schema catalog resolves each table from the database, and this table has no id the call can use: no primary key, a primary key of several columns, or one of a type ARX can't use as an id. Refused before anything is sent, only for a call that needs the id (Create, Retrieve, Update or Delete by id). Declare the table in a schema catalog (`ArxIdColumn.NoIdColumn`), or match by a key or columns. | no | no database error maps to it (ARX itself can still raise it) |

## ARX2xxx NotFound

The rows the call addressed weren't found as asked: none, several where one was required, or one at another version than the call carried (ARX2004). Nothing was changed.

| Code | Name | Meaning | Safe to retry | From MySQL |
|---|---|---|---|---|
| ARX2002 | `RecordNotFound` | The record addressed by key doesn't exist. | no | `1411 (ARX's check)` an update or delete whose rows weren't all found: ARX's own check in the statement |
| ARX2003 | `MultipleRecordsMatched` | An update or delete with `RequireSingleRow` found more than one row for an entity. Nothing was changed. | no | `1411 (ARX's check)` an entity that matched several rows when one was required: ARX's own check |
| ARX2004 | `RecordChanged` | The record was changed since it was read: an Update or Delete carried a version (optimistic concurrency) that isn't the record's any more. Nothing was changed: read it again, and apply the change to what is there now. | no | no database error maps to it (ARX itself can still raise it) |

## ARX3xxx Constraint

The database refused the change because of a rule: a unique key, a foreign key, NOT NULL, CHECK, or a routine's own error.

| Code | Name | Meaning | Safe to retry | From MySQL |
|---|---|---|---|---|
| ARX3001 | `UniqueViolation` | A unique constraint or key was violated. | no | `1062` duplicate entry for a unique key; `1586` duplicate entry for a named unique key |
| ARX3002 | `ForeignKeyViolation` | A referenced record is missing, or a record is still referenced. | no | `1216` a child row's foreign key has no parent row (older form); `1217` a parent row is still referenced by child rows (older form); `1451` a parent row is still referenced by child rows; `1452` a child row's foreign key has no parent row |
| ARX3003 | `NotNullViolation` | A required attribute has no value. | no | `1048` NULL into a NOT NULL column; `1364` a column with no default value was left out |
| ARX3004 | `CheckViolation` | A check constraint or validation rule failed. | no | `3819` a check constraint is violated |
| ARX3005 | `RaisedByDatabase` | A routine the database runs (a procedure or function) refused the call on purpose (PostgreSQL `RAISE EXCEPTION`, SQL Server `THROW`, MySQL `SIGNAL`). On PostgreSQL: `RAISE EXCEPTION` (SQLSTATE P0001), an `ASSERT` or a state of the routine's own (`USING ERRCODE = 'AX001'`). The message is the routine's; `SqlState`, `Detail` and `Hint` are its own. | no | `1644, SQLSTATE 45000` SIGNAL SQLSTATE '45000', with MySQL's number or the MYSQL_ERRNO the routine sets |

## ARX4xxx Data

A value doesn't fit its column: out of range, too long, in the wrong format or of the wrong type.

| Code | Name | Meaning | Safe to retry | From MySQL |
|---|---|---|---|---|
| ARX4001 | `ValueOutOfRange` | A number is outside the column's range. | no | `1264` a number out of its column's range; `1365` division by zero; `1441` a date or time past its type's range after rounding (datetime field overflow); `1690` a value out of its type's range in an expression |
| ARX4002 | `ValueTooLong` | Text or binary data is longer than the column allows. | no | `1153` a statement larger than max_allowed_packet; `1153 (driver)` a command larger than max_allowed_packet, refused by MySqlConnector; `1406` data too long for a column |
| ARX4003 | `InvalidValueFormat` | A value can't be parsed for its column (for example invalid JSON, dates or encoding). | no | `1265` data truncated for a column (an ENUM or SET value it doesn't have); `1292` an incorrect value: a date or time its column can't hold (not a date, or out of the type's range), or text that isn't a number; `1366` a value its column's type can't read; `1411` a value a function's type can't read; `3140` invalid JSON text for a JSON column; `3141` invalid JSON text for a JSON function |
| ARX4004 | `DataTypeMismatch` | A value's type doesn't fit the column. | no | `1267` an illegal mix of collations; `1271` an illegal mix of collations (three); `1318` the wrong number of arguments for a procedure or function; `1414` an OUT or INOUT argument that isn't a variable |

## ARX5xxx Schema

A table or column doesn't exist, or a declaration in the schema catalog doesn't match the table.

| Code | Name | Meaning | Safe to retry | From MySQL |
|---|---|---|---|---|
| ARX5001 | `UndefinedEntity` | The table or collection doesn't exist. | no | `1146` the table doesn't exist; `1305` the procedure or function doesn't exist |
| ARX5002 | `UndefinedAttribute` | The column doesn't exist or can't be written. | no | `1054` unknown column; `1055` a column neither grouped nor aggregated (ONLY_FULL_GROUP_BY); `1140` an aggregate with a column that isn't aggregated and no GROUP BY; `3105` a value for a generated column |
| ARX5003 | `SchemaMismatch` | A declaration in the schema catalog doesn't match the table: the database returned an id of another type, or `ValidateSchemaAsync` found a difference. The exception says whether rows were stored. | no | no database error maps to it (ARX itself can still raise it) |

## ARX6xxx Permission

The database user isn't allowed to do it.

| Code | Name | Meaning | Safe to retry | From MySQL |
|---|---|---|---|---|
| ARX6001 | `PermissionDenied` | The database user lacks the required permission. | no | `1044` the user has no access to the database; `1045` access denied (login failed); `1142` the user lacks a privilege on the table; `1143` the user lacks a privilege on a column; `1227` the operation needs a privilege the user lacks; `1290` the server's options refuse the statement (read-only); `1370` the user lacks a privilege on the routine |

## ARX7xxx Transient

A temporary failure: a deadlock, a conflict, a timeout, throttling or a lost connection. Safe to retry the whole operation (`IsTransient` is true).

| Code | Name | Meaning | Safe to retry | From MySQL |
|---|---|---|---|---|
| ARX7001 | `Deadlock` | The operation was chosen as a deadlock victim. Safe to retry. | yes | `1213` deadlock: the transaction was rolled back |
| ARX7002 | `SerializationFailure` | The operation conflicted with a concurrent transaction. Safe to retry. | yes | no database error maps to it (ARX itself can still raise it) |
| ARX7003 | `Timeout` | The command or a lock wait timed out. Safe to retry. | yes | `-1` the command timed out (client); `1205` lock wait timeout (the statement was undone); `1317` the statement was interrupted (KILL QUERY: a client timeout or cancellation); `3024` the statement's maximum execution time was exceeded |
| ARX7004 | `Throttled` | The server is rate-limiting or out of connections. Safe to retry later. | yes | `1040` too many connections; `1203` the user has too many connections; `1226` the user exceeded a resource limit |
| ARX7005 | `ConnectionFailure` | The database couldn't be reached, or the connection dropped. Safe to retry. | yes | `1042` the server can't be reached; `1049` unknown database; `1053` the server is shutting down; `1927` the connection was killed; `2002` can't connect to the server; `2003` can't connect to the server on its port; `2006` the server has gone away; `2013` the connection was lost during a query; `driver` MySqlConnector couldn't reach the server, or the connection broke |

## ARX8xxx NotSupported

The provider can't do what was asked, and refuses it rather than ignoring part of it.

| Code | Name | Meaning | Safe to retry | From MySQL |
|---|---|---|---|---|
| ARX8001 | `NotSupported` | The provider doesn't support the requested operation or feature. | no | `1064` a syntax error; `1191` full-text search on a column without a FULLTEXT index; `1235` a feature this MySQL version doesn't support; `1288` the target view or table isn't updatable; `1393` a change through a join view would affect several base tables; `1395` a delete from a join view; `1422` a commit inside a stored function or trigger; `1442` a function or trigger changes a table the statement uses; `1471` the target view isn't insertable; `1792` a write in a READ ONLY transaction |

## ARX9xxx Provider

A database error ARX doesn't map; the exception keeps its native code and SQLSTATE.

| Code | Name | Meaning | Safe to retry | From MySQL |
|---|---|---|---|---|
| ARX9001 | `ProviderError` | A native error the provider doesn't map; see NativeCode and SqlState. | no | any other error number |

