Up Save

Handle save errors

Last modified on August 15, 2012 17:21

The SaveResult returned by both synchronous and asynchronous SaveChanges calls provides information which can help you handle save errors.


SaveResult.Ok returns "true" if the save was successful. If the save was canceled in a life-cycle handler, SaveResult.WasCancelled will return "true" and SaveResult.Ok will return "false". 

If a save fails for any reason except 'Cancelation' an EntityManagerSaveException is raised.  For synchronous SaveChanges calls the exception is thrown, while in SaveChangesAsync calls the exception is available on the EntitySaveOperation.

Handling the exception

You should prepare your code to trap and analyze the save exception.  The EntityManagerSaveException has the information you need to help diagnose and handle the problem.

Always handle save exceptions.

  • Wrap every call to EntityManager.SaveChanges() in your own custom Save method.
  • Wrap every synchronous SaveChanges in a Try/Catch
  • Add error logic to every asynchronous SaveChangesAsync to analyze the exception.
  • For asynchronous calls, remember to call MarkErrorAsHandled unless the application should terminate.

Here’s a code fragment showing a SaveAll method that matches our recommendation:

C#
internal void SaveAll() {
 try {
    MainEm.Manager.SaveChanges();// Save everything                         
   DisplaySaveOk();
  } catch (EntityManagerSaveException saveException) {
    ProcessSaveFailure(saveException);
  } catch {
   throw; // re-throw unexpected exception
 }
}
VB
Friend Sub SaveAll()
 Try
    MainEm.Manager.SaveChanges() ' Save everything
   DisplaySaveOk()
 Catch saveException As EntityManagerSaveException
    ProcessSaveFailure(saveException)
 Catch
   Throw ' re-throw unexpected exception
 End Try
End Sub

The serious failure interpretation and recovery work is in the ProcessSaveFailure method, which we leave to you.  Your application should determine how to process save errors, and recover from then when possible.

EntityManagerSaveException

The EntityManagerSaveException is raised for all save-related exceptions.

If you've added a handler to the EntityManager's EntityServerError  event, that handler will be called first when a save-related exception occurs.  If there is no handler or it doesn’t handle the exception, the EntityManager throws it again, now in the context of the SaveChanges call.

We recommend that you do not handle save exceptions in an EntityServerError handler; leave that to the code near your SaveChanges call that traps and interprets save failures.

The EntityManagerSaveException inherits from EntityServerException, supplementing it with information about which entity/entities in the local cache caused the problem. 

There are several properties on the EntityManagerSaveException that can be very useful in diagnosing the problem that occurred. 

PropertyProperty typeDescription
EntitiesWithErrors IList<Object>A list of the entities with errors. In practice, this will usually be a list of one -- the first entity to fail --.  The idea here is that a non-transactional save might have multiple errors because one error would not stop the process, or multiple entities may have failed validation.  Since DevForce only offers transactional saves to the datastore, the first entity to fail within a transaction causes the transaction to rollback, so no other entities are saved. 
InnerException ExceptionThe precipitating exception, whether from an attempt to connect to the data source or an exception from the data source itself such as a concurrency conflict or referential integrity violation.
FailureType FailureType

A classification of the error that cause the problem.  Several FailureTypes are possible.

FailureType    Description
ConnectionThe Entity Manager could not reach the data source. There might be a network connection problem or the data source itself could be down.
DataThe data source threw an exception such as a referential integrity violation.
ConcurrencyThere was a concurrency conflict.
Validation  One or more entities failed server-side validation. 
OtherCould be anything.

What happens to any local entities after a save fails

These entities remain in the cache and retain exactly the values and setting they had before the save attempt.  This means that you may be able to correct the entities and attempt to re-save them.  

Created by DevForce on February 19, 2011 12:51

This wiki is licensed under a Creative Commons 2.0 license. XWiki Enterprise 3.2 - Documentation. Copyright © 2015 IdeaBlade