How to handle Java Callout errors

You're viewing Apigee X documentation.
View Apigee Edge documentation.

What is a Java callout?

If you're new to Java callouts, we recommend that you start with How to create a Java callout.

Handling errors in a Java Callout

When you write a Java Callout, you may want to do custom error handling in your Java code. For example, you may wish to return custom error messages and headers and/or set flow variables with error information in the proxy flow on Apigee.

Let's walk through a simple Java Callout example that illustrates basic custom error handling patterns. The sample returns a custom error message when an exception occurs. It also places the error stacktrace into a flow variable, which can be a handy debugging technique.

Download the project

To make things simple, you can download this project from the Apigee api-platform-samples repository on GitHub.

  1. Download or clone api-platform-samples to your system.
  2. In a terminal or code editor of your choice, go to the api-platform-samples/doc-samples/java-error project.

The sample Java code

The error handling patterns are straightforward. You can set flow variables in the current Apigee flow context with the messageContext.setVariable() method. To return custom error information, construct an ExecutionResult instance and call methods on it to set the error response and headers.

package com.apigeesample;

import com.apigee.flow.execution.ExecutionContext;
import com.apigee.flow.execution.ExecutionResult;
import com.apigee.flow.execution.spi.Execution;
import com.apigee.flow.message.MessageContext;
import com.apigee.flow.execution.Action;

import org.apache.commons.lang.exception.ExceptionUtils;


public class JavaError implements Execution {
    public ExecutionResult execute(MessageContext messageContext, ExecutionContext executionContext) {

        try {

                String name = messageContext.getMessage().getHeader("username");

                if (name != null && name.length()>0) {
                        messageContext.getMessage().setContent("Hello, " + name + "!");
                        messageContext.getMessage().removeHeader("username");

                } else {
                        throw new RuntimeException("Please specify a name parameter!");
                }

                return ExecutionResult.SUCCESS;

        } catch (RuntimeException ex) {

            ExecutionResult executionResult = new ExecutionResult(false, Action.ABORT);

            //--Returns custom error message and header
            executionResult.setErrorResponse(ex.getMessage());
            executionResult.addErrorResponseHeader("ExceptionClass", ex.getClass().getName());

            //--Set flow variables -- may be useful for debugging.
            messageContext.setVariable("JAVA_ERROR", ex.getMessage());
            messageContext.setVariable("JAVA_STACKTRACE", ExceptionUtils.getStackTrace(ex));
            return executionResult;
        }
    }
}


Compile your code with Maven

The project is set up so that you can compile with Maven. If you want to use javac, we'll include an example as well.

  1. Be sure that you have Maven installed:
    mvn -version
    
  2. Execute the script java-error/buildsetup.sh. This script installs the required JAR dependencies in your local Maven repo.
  3. cd to the java-error/callout directory.
  4. Execute Maven:
    mvn clean package
    
  5. If you wish, verify that the JAR file edge-custom-policy-java-error.jar was copied to java-error/apiproxy/resources/java. This is the required location for JAR files that you wish to deploy with a proxy.

Compile with javac

If you want to use javac to compile the code, you can do something similar to the following (from the java-error directory). The required JAR files are provided for you in the java-error/lib directory.

  1. cd to api-platform-samples/doc-samples/java-error.
  2. Be sure you have javac in your path.

    javac -version
    
  3. Execute the following javac command:

    javac -d . -classpath ./lib/expressions-1.0.0.jar:./lib/message-flow-1.0.0.jar:. callout/src/main/java/JavaProperties.java
    
  4. Copy the JAR file to the apiproxy/resources/java directory. This is the required location for JAR files that you wish to deploy with a proxy.

    cp com/apigeesample/JavaProperties.class apiproxy/resources/java
    

Deploy and call the proxy

A deploy script is provided in the ./java-error directory. But before you run it, you need to do a quick setup.

  1. cd to api-platform-samples/doc-samples/java-error
  2. The simplest way to deploy the proxy is to bundle it in a zip file and upload the proxy bundle to an environment in your Apigee organization. See Creating an API proxy. Be sure to use the Upload Proxy Bundle option. See also Tips and tricks for uploading API proxy in a proxy bundle in the Apigee community.
  3. When the proxy is deployed, try calling it:
    curl  https://$HOSTNAME/java-error

    Because the call does not include a "name" query parameter, the Java code throws a runtime error. The proxy returns this message and header:

  • Error message: Please specify a name parameter!
  • Header: ExceptionClass: java.lang.RuntimeException