0

How do I force my database transaction when a exception is thrown. I am trying to insert a record in finally block but throwing an exception in catch block.

try {
...
} catch(Exception e) {
throw e;
} finally {
log__c log = new log__c;
insert log__c;
}

It throws the exception but doesn't insert a record in log object. How do I force commit this transaction even when the exception is thrown?

please help.

2
  • a more likely pattern is to set a savepoint first at the beginning of the try, rollback in the catch, and then insert a log record in the catch
    – cropredy
    Aug 28, 2015 at 22:12
  • hi keith.. can u pls tell me how did u format my code in the above question.. whenever i paste some code it doesnt show up or comes misaligned?
    – user10930
    Aug 29, 2015 at 15:11

2 Answers 2

2

Finally only runs after all exception handlers have successfully handled the exception. Since you threw the exception, it went up the stack, so finally isn't called. If you wanted to commit a record and throw the exception up the stack, you'd do:

try {
   ...
} catch(Exception e) {
    Log__c logRecord = new Log__c(/* put details here */);
    insert logRecord;
    throw e;
}

However, please note that if e reaches the top of the stack without being caught (and handled), the entire transaction will explode, and your log will be vaporized along with the rest of the transaction. So, if you're doing this in a trigger, you probably want to just swallow the exception, although this means your records will be in a potentially out-of-sync state.

Also, please vote on this idea to allow us to have transactions that completely fail but still save some custom debugging data.

In Visualforce, you can do this:

public void doSomething();
     SavePoint sp = Database.setSavePoint();
     try {
         // Do stuff here
     } catch(Exception e) {
         Database.rollback(sp);
         insert new Log__c(...);
         ApexPages.addMessages(e);
     }
}

You can do a similar context in custom REST/SOAP functions. You cannot effectively do this in a trigger, because any errors reported or exceptions thrown will roll back the entire transaction (retries are done after the rollback).

3
  • Hi sfdcfox, I did what you suggested. Basically insert first and throw in catch block. i see that in debug logs its inserting to the object.. but however end result is i dont see that record in database. we are basically throwing errors because this is backend code and we want to handle the exception in our UI. so I need to throw some exception to UI as well log a record(exception details) in this custom object..
    – user10930
    Aug 29, 2015 at 1:12
  • 1
    @user10930 To be clear, if you get an exception back to the top, nothing will be saved. If you want to show an error and persist data, you have to do so in a context that supports this. For example, inside a controller in Visualforce, or a custom rest service or soap call. You can't do this directly in a trigger, because if the transaction receives an exception that's unhandled, all changes roll back. See my idea that I mentioned.
    – sfdcfox
    Aug 29, 2015 at 1:17
  • @user10930 I added some more details for when/how you can safely report an error and still retain some data.
    – sfdcfox
    Aug 29, 2015 at 1:21
0

I realised throwing an exception as well persisting data cannot happen at the same point. so I'm persisting data to the custom object in the front end where I am catching this exception.

thanks for all ur brilliant help on this question.

regards, priyanka.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.