Handling exceptions


While working with BMC Helix Innovation Studio services APIs, you might come across runtime exceptions (RxException) that contain error codes. You can use these error codes to define a mapping of exceptions with HTTP error responses. The error codes can be used with @RxRestError annotation in a JAX-RS resource. For example, you can configure an annotation in way that the error code is associated with a 404 response code and the Jersey error handler can automatically set the response code correctly. Errors are modeled through the RxException class.

  • You can extend the RxException class (com.bmc.arsys.rx.services.RxException.java in BMC Helix Innovation Studio SDK).
  • You can customize the HTTP status code sent to a REST API client for an exception in our custom REST resource class using an annotation.
  • You can specify which error code should result in HTTP status 404.
  • You also can add an application level error message that is displayed before any other messages in RxException.

Overview of REST API error messages

A REST API returns two levels of error information:

  • HTTP error codes and messages in the response header
  • A JSON object in the response body with additional details

 The error message information is provided in the following format:

  • message type
  • message number
  • message text
  • appended text

 The following code sample represents the format of the message you receive when an error occurs:

[
 {
   "messageType": "ERROR",
"messageNumber": 303,
"messageText": "Record Definition does not exist on server.",   
   "appendedText": "com.example:non-existent-rd"
 }
]

When any Digital Service application license related error occurs, REST API returns the HTTP response status 403 (Forbidden).

@RxRestError annotation

The @RxRestError annotation lets you specify the framework how to handle uncaught exceptions and specify which error code should result in HTTP status 404. It also allows you to specify an application level error code for any occurrence of uncaught exception.

Handling exceptions using RxException subclass

When you create Java service APIs, you can use the RxException subclass (com.bmc.arsys.rx.services.RxException.java in BMC Helix Innovation Studio SDK) to handle exceptions.

  1. Create an exception class that extends the RxException class. The following is a sample code:

    public class MyException extends RxException {

        private static final String BUNDLE_ID = "com.example.myapplication";

       public MyException(int messageNum) {
            this(messageNum, null, (Throwable) null);
       }

       public MyException(int messageNum, String appendedText) {
            this(messageNum, appendedText, (Throwable) null);
       }

       public MyException(int messageNum, String appendedText, RxException e) {
            super(messageNum, BUNDLE_ID, appendedText, e);
       }

       public MyException(int messageNum, String appendedText, Throwable t) {
            super(messageNum, BUNDLE_ID, appendedText, t);
       }

    }
  2. Define message constants or enum.

    Create a constant class for message numbers that you want to put in LocalizationService. This provides you a single location to reference your message numbers. The following is a sample message constant class:

    public final class MyMessage {

       public static final int ITEM_NOT_FOUND = 10_100;

       public static final int ITEM_ACCEPTED = 10_101;

       public static final int ERROR_CREATING_ITEM = 10_102;

       /**
         * Make the default constructor private since this class is not meant to be instantiated.
         */

        private MyMessage() {
       }

    }

    You can define enum instead of constant files. If you define enum, you must change your MyException class to accept the enum instead of int. The following is a sample code:

    public enum MyMessage {

       ITEM_NOT_FOUND(10_100),
       ITEM_ACCEPTED(10_101),
       ERROR_CREATING_ITEM(10_102);

       private final int intValue;

       MyMessage(int intValue) {
           this.intValue= intValue;
        }

       public int intValue() {
           return messageNum;
        }

    }

    public class MyException extends RxException {

       private static final String BUNDLE_ID = "com.example.myapplication";

       public MyException(MyMessage errorMessage, String appendedText, RxException e) {
           super(errorMessage.intValue(), BUNDLE_ID, appendedText, e);
        }

    }
  3. For every message that you have defined, add a message text in LocalizationService. See Localizing error messages.
  4. (Optional) If you are creating application layer classes (for example, resources, commands, or data page queries),  you can add @RxRestError annotation to specify an application level error message and declare the error code that should result in HTTP status 404.
    The following is a resource sample:

    public class MyResource implements RestfulResource {

        @GET
        @Path("{name}")
       // removing other annotations for brevity
        @RxRestError(notFoundErrorCode = MyMessage.ITEM_NOT_FOUND)
       public Item get(@PathParam("name") String name) {
           // TODO
           return null;
        }

        @POST
       // removing other annotations for brevity
        @RxRestError(applicationErrorCode = MyMessage.ERROR_CREATING_ITEM)
       public String post(Item item) {
           // TODO
           return null;
        }

    }


 

Tip: For faster searching, add an asterisk to the end of your partial query. Example: cert*