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).
try
,rollback
in the catch, and theninsert
a log record in the catch