Generated code - Handling exceptions
Preface
Exceptions are considered 'exceptional' in the runtime libraries and generated code. This means that exceptions are used to illustrate an exceptional state
which has to be addressed. They're not used to report a semantic failure. An example of a semantic failure is the save of a single entity without recursion. This save
can fail due to various reasons. The save logic in the template groups will return false in that case and not an exception: the action simply failed. If an
error occurs in the code, due to input or a code error, the code does throw exceptions or will simply bubble up the exception. If the exception is an
exception which should be handled locally, the runtime
libraries or the generated code will try to handle the exception and only if nothing helps it will be passed upwards. This can sometimes mean that the exception is
encapsulated in a custom exception to provide more information about the error caught, for example when a query failed, the complete query is included in the exception.
You should always check for return values if the method returns a return value, for example true or false as your primary result check. You should add try/catch clauses
if you need local handling of the exceptions thrown, otherwise you can better bubble it up and handle it in a global exception handler routine. Because exceptions are
only thrown in the case of an error (programmatic or via input), you don't have to add long exception catch clauses, as only in the case of an error an exception is
thrown, which means you have to have error-recovery in place to successfully handle the error further.
Custom exceptions
Below are listed the custom exceptions as they're thrown by the generated code and runtime libraries. All exceptions are serializable and should be able to pass
remoting boundaries. The exception classes are defined in the ORM Support classes library. See the reference manual for details about the classes. All custom
exceptions are derived from the common base class ORMException.
- ORMConcurrencyException. This exception can be thrown in two situations:
- During a save of one or more entities.
When, during a save action, a save fails, i.e. doesn't affect any rows the exception will be thrown. This can be
caused by the fact that the row being updated is already deleted, or the predicate created by the set ConcurrencyPredicateFactory or the
passed in predicate caused a failure of the update due to a concurrency violation.
The exception will terminate the transaction started during a recursive save and will therefore make a recursive save action completely atomic.
- During a delete of an entity with a delete restriction.
When a delete action of an entity fails and a delete restriction predicate has been specified, for example by an IConcurrencyPredicateFactory, this
exception is thrown. Any running transaction will be terminated. A delete action without a delete restriction won't throw this exception, even in the
situation the delete failed.
- ORMEntityIsDeletedException. This exception is thrown when an entity's field's is read after the entity was deleted from the database using the
SelfServicing method IEntity.Delete() or via the Adapter method DataAccessAdapter.DeleteEntity(). It doesn't intercept deletes which are done on the
database directly through DeleteEntitiesDirectly() (Adapter) or DeleteMulti() (SelfServicing).
- ORMEntityOutOfSyncException. (Adapter specific) This exception is thrown when a entity's field's value is read right after a save action and
the entity is not fetched back. Fetching an entity back after a save action is not always preferred so it is not enabled by default. This exception
illustrates you've forgotten to specify in the SaveEntity() call or SaveEntityCollection() call that the entity to save should be refetched after the
save action.
- ORMEntityValidationException. This exception is meant to be thrown by validation code written by you, in either validation code added to entities
or by code added to a validator class. See: Generated code - Validation per field or per entity
- ORMFieldIsNullException. This exception is thrown when a fields value is read after it was explicitly set to null/Nothing using the
entity method SetNewFieldValue(). This method SetNewFieldValue is sometimes used to set a field in an existing entity to NULL prior to saving that entity.
- ORMFieldIsReadonlyException. This exception is thrown when a read-only entity field's setter clause is called.
Read-only fields are fields which do not require a value before the entity is saved, like sequenced (identity) fields or timestamps (on SqlServer).
If your code then tries to set such a field to a value, you'll get this exception.
- ORMGeneralOperationException. This exception is thrown when
the general operation of the o/r core isnt used correctly, like bad
imput has been given and no other exception is appropriate.
- ORMInheritanceInfoException. This exception is meant for errors determined during query execution, for example when the
inheritance info data is out of sync with the data in the db, which occurs for example when the type has to be determined
of the row retrieved from the db and the discriminatorvalue is unknown to the generated code.
- ORMInterpretationException. This exception is thrown when an
interpretation error occurs during predicate/sortclause interpretation
for filtering or sorting in-memory inside an EntityView(2).
- ORMInvalidFieldReadException. This exception is thrown when a
field of an entity class instance is read while it hasn't been set to a
value yet. Only thrown when the EntityBase(2).MakeInvalidFieldReadsFatal
flag is set to true (default is false).
- ORMQueryConstructionException. This exception is thrown when an error occurs in the Dynamic Query Engine,
Linq provider or QuerySpec engine during the construction of a SQL query
from the input query.
- ORMQueryExecutionException. This exception is thrown when an error occurs in the ADO.NET provider during a database action. The exception itself
contains the complete query executed and the exception caught as inner exception. The parameters used are also included in the exception object, however
these are not serialized when the exception object is passed through remoting, as ADO.NET parameters aren't serializable. The exception also contains a Dictionary with the database specific exception information, stored per exception element, with ExceptionInfoElement values as key.
- ORMRelationException. This exception is thrown when something is wrong with a relation or with the context
the relation is used in (ToQueryText in a RelationCollection for example)
- ORMSecurityException. This exception isn't used by the LLBLGen Pro runtime framework but can be used by your code to report authorization failures in Authorizers or Authorization logic.
- ORMValueTypeMismatchException. This exception is thrown when an entity's field is set to a value which isn't matching the type of the field. This
can only happen with non-value typed fields using the properties of an entity class or when using the SetNewFieldValue() method.