Handling exceptions

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 what can happen when you save 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.
  • ORMBadSequenceException. This exception is thrown if a sequence retrieval query(fragment) returns null before/after an insert, due to wrong sequence semantics or the field isn't marked as identity in the database while the mapping code defines it as a sequenced field. The exception contains the query executed.
  • ORMConfigurationException. This exception is thrown when an error is detected in the RuntimeConfiguration system usage.
  • 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.
  • ORMTransientRecoveryFailedException. This exception is thrown when the LLBLGen Pro Runtime Framework couldn't recover a transient error using the strategy provided.
  • 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.