How to use TRAP

Provides code snippets to show you how to use TRAP.

Execute leaving functions under a trap harness

Functions that leave, including functions that call other functions that can leave, must be executed under a trap harness.

If a call to User::Leave() occurs within the function, control will immediately be returned to the most recent TRAP. A variable is used with every trap to receive the error code specified in a leave.

If no leave occurs, then when the called function ends, execution returns to the TRAP, and the leave variable has the value KErrNone.

Typically after a TRAP, a function checks the leave variable to test whether processing returned normally or by leaving, and acts appropriately. Special mechanisms discussed later are provided to handle cleanup after the exception.

TInt E32Main() 
 {  
 testConsole.Title(); // write out title
 testConsole.Start(_LIT("Example")); // start a new "test"

 // The leave variable
 TInt r;
 // Perform example function. If it leaves,
 // the leave code is put in r
 TRAP(r,doExampleL()); 
 // Test the leave variable
 if (r) 
  testConsole.Printf(_LIT("Failed: leave code=%d"), r);

 testConsole.End(); // finish
 testConsole.Close(); // close it
 return KErrNone; // and return
 }

Notes

  • It is not necessary that all L functions be directly invoked by a trap harness. In most cases, functions that can leave are called normally by other functions. It is only necessary that somewhere above the function in the call chain is a trap harness.

  • It is not recommended to call a function with an LC suffix from inside a trap harness. This is because if the function does not leave, the object that the function created and pushed onto the cleanup stack will remain on the cleanup stack on exiting from the trap harness. This causes a E32USER-CBase 71 panic, unless the object is popped by the caller from within the trap harness, for example:

    TRAPD(error, pointer = SomeClass::SomeFunctionLC(); CleanupStack::Pop(pointer));

    In this code, if SomeClass::SomeFunctionLC() leaves, then pointer is destroyed as part of leave processing. If it does not leave then CleanupStack::Pop(pointer) is called, avoiding the panic.

Using TRAPD

For convenience, there is a TRAPD form of the macro which defines the variable to be used as the leave code. This saves a line of source code in the majority of situations.

TRAPD(leaveCode,SomeFunctionL()); // call a function
if (leaveCode!=KErrNone)          // check for error leave code
 {
 // some cleanup
 }

Trap harnesses and function return values

Trap harnesses can be used when the function being called returns a result.

TRAPD(leaveCode,value=GetSomethingL()); // get a value
if (leaveCode!=KErrNone) // check for error leave code
 {
 // some cleanup
 }
else { // didn’t leave: value valid
 }