Provides code snippets to show you how to use TRAP.
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.
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 }