26 Displaying Error Messages in MAF Applications

This chapter describes how to use the AdfException class to handle errors and how to localize error messages.

This chapter includes the following sections:

26.1 Introduction to Error Handling in MAF Applications

Errors arising from mobile applications might be unexpected, such as a failed connection to a remote server, or expected, such as a violation of an application business rule. Errors or exceptions might occur in the primary request thread or in a secondary thread that runs a background task. If the application supports multiple languages, then it must display the error message in the user's language.

To enable a mobile application to throw an exception, use oracle.adfmf.framework.exception.AdfException class. For more information, see .

The following code enables MAF to handle an exception gracefully. A popup message, similar to the one illustrated in Figure 26-1 displays within the application and shows the message severity and explanatory text.

throw new AdfException("My error message",AdfException.ERROR);

Figure 26-1 An Error Message

This image is described in the surrounding text

Note:

Similar error messages display within application when the exception is thrown within a managed bean or a data control bean.

26.2 Displaying Error Messages and Stopping Background Threads

The MessageUtils class, illustrated in the example below, enables an application to stop a thread and display an error by first making a JavaScript call (invokeContainerJavaScriptFunction) and then throwing an exception. The addMessage method enables the error to display. For more information, see How Applications Display Error Message for Background Thread Exceptions. See also invokeContainerJavaScriptFunction.

The MessageUtils class uses the BundleFactory and Utility methods for retrieving the resource bundle and the error message and dynamically checks if a thread is running in the background. Using this class, you can move code from the main thread to the background thread.

package oracle.errorhandling.demo.mobile;
 
import java.util.ResourceBundle;
 
import oracle.adfmf.framework.api.AdfmfContainerUtilities;
import oracle.adfmf.framework.api.AdfmfJavaUtilities;
import oracle.adfmf.framework.exception.AdfException;
import oracle.adfmf.util.BundleFactory;
import oracle.adfmf.util.Utility;
 
public class MessageUtils{  public static void handleError(AdfException ex)  {    handleMessage(ex.getSeverity(), ex.getMessage());  }  public static void handleError(String message)  {    handleMessage(AdfException.ERROR, message);  }  public static void handleError(Exception ex)  {    handleMessage(AdfException.ERROR, ex.getLocalizedMessage());  }  public static void handleMessage(String severity, String message)  {    if (AdfmfJavaUtilities.isBackgroundThread())    {      AdfmfContainerUtilities.invokeContainerJavaScriptFunction(AdfmfJavaUtilities.
                                                                getFeatureName(),
                                                                "adf.mf.api.amx.addMessage",
                                                                 new Object[] {severity,                                                                                message,
                                                                               null,
                                                                               null});

      if (AdfException.ERROR.equals(severity))      {        // we still need to throw execption to stop background thread processing        throw new AdfException(message,severity);             }    }    else    {      throw new AdfException(message,severity);    }     }}
    public static void addJavaScriptMessage(String severity, String message) {
        AdfmfContainerUtilities.invokeContainerJavaScriptFunction(AdfmfJavaUtilities.
                                                                  getFeatureName(),
                                                                  "adf.mf.api.amx.addMessage",
                                                                   new Object[] {severity,
                                                                                 message,
                                                                                 null,
                                                                                 null });


    }
}

26.2.1 How Applications Display Error Message for Background Thread Exceptions

Applications do not display error messages when exceptions are thrown for background threads. To enable error messages to display under these circumstances, applications call the addMessage method. The addMessage method takes the following parameters:

  • The severity of the error

  • The summary message

  • The detail message

  • a clientComponentId.

The example below illustrates how you can enable the application to alert the user when an error occurs in the background by using the addMessage method.

Runnable runnable = new Runnable()
{
  public void run()
  {
    AdfmfContainerUtilities.invokeContainerJavaScriptFunction(AdfmfJavaUtilities.getFeatureName(),
      "adf.mf.api.amx.addMessage", new Object[] {AdfException.ERROR, 
                                                 "My error message for background thread",
                                                 null,
                                                 null });
  }
};
Thread thread = new Thread(runnable);
thread.start();

Because the adf.mf.api.amx.addMessage JavaScript function is the same method that is used when the application throws AdfException in the primary request thread, users receive the same popup error message whether the error message is referring to exceptions in the main thread or from a background thread.

Note:

As illustrated in the example above, the detail message and the clientComponentId can be a Null value. A detail message displays on a new line in the same font size as the summary message.

However, you can prevent an error message from appearing if you place the code within a piece of Java logic that runs in a background thread, as illustrated in the following example. Using the method illustrated in the first example of Localizing Error Messages enables the background thread to stop silently without notifying the user.

Runnable runnable = new Runnable() {
   public void run() {
      // this exception will be lost because no popup error
      // message will display in the MAF application
      throw new AdfException("My (lost) error message in background",
                              AdfException.ERROR);
   }
};
Thread thread = new Thread(runnable);
thread.start();

26.3 Localizing Error Messages

MAF uses standard Java resource bundles to display an exception error message in the language of the application user. As illustrated in the example below, the resource bundle name (the .xlf file) and bundle message key is passed to the AdfException constructor method to enable the error message to be read from a resource bundle.

private static final String XLF_BUNDLE_NAME="oracle.errorhandling..mobile.ViewControllerBundle";
   throw new AdfException(AdfException.ERROR, XLF_BUNDLE_NAME,
                                             "MY_ERROR_MESSAGE",
                                              null);

To ensure that the application does not throw an MissingResourceException error, use the oracle.adfmf.util.BundleFactory method to retrieve the resource bundle and then use the oracle.adfmf.util.Utility method to retrieve the error message, as illustrated in the example below.

ResourceBundle bundle = BundleFactory.getBundle(XLF_BUNDLE_NAME);
String message = Utility.getResourceString(bundle, "MY_ERROR_MESSAGE",null);
throw new AdfException(message,AdfException.ERROR);

The next example illustrates using the adf.mf.api.amx.addMessage JavaScript function to display the localized error message when an exception is thrown from a background thread.

ResourceBundle bundle = BundleFactory.getBundle(XLF_BUNDLE_NAME);
String message = Utility.getResourceString(bundle, "MY_ERROR_MESSAGE_BG",null);
AdfmfContainerUtilities.invokeContainerJavaScriptFunction(AdfmfJavaUtilities.
                                        getFeatureName(),
                                        "adf.mf.api.amx.addMessage",
                                         new Object[] {AdfException.ERROR,
                                                                    message,
                                                                    null,
                                                                    null });