# How to Implement Custom Error Code Handlers Using LinkisErrorCode Interfaces for Engine-Specific Exceptions

> Implement custom error code handlers for engine specific exceptions in Apache Linkis. Learn how to use LinkisErrorCode interfaces to map exceptions and register handlers effectively.

- Repository: [The Apache Software Foundation/linkis](https://github.com/apache/linkis)
- Tags: how-to-guide
- Published: 2026-02-25

---

**To implement custom error code handlers for engine-specific exceptions in Apache Linkis, create an enum implementing `LinkisErrorCode`, then implement the `ExceptionErrorCodeHandler` interface to map engine exceptions to those codes, and register the handler via the `LinkisErrorCodeFactory` or direct instantiation.**

Apache Linkis provides a pluggable error code framework that standardizes how engine exceptions are reported across the platform. By implementing the `LinkisErrorCode` interface and creating custom `ExceptionErrorCodeHandler` implementations, you can map engine-specific failures to structured error codes that integrate seamlessly with Linkis's error handling infrastructure.

## Understanding the Linkis Error Code Architecture

The framework centers on three core interfaces defined in `linkis-pes-client`. The base `ErrorCodeHandler` interface provides the foundational contract, while `ExceptionErrorCodeHandler` specifically targets engine-specific `Throwable` objects. The default implementation, `LinkisErrorCodeHandler`, aggregates multiple handler types but contains a stub `handle(Throwable)` method that returns `null` at lines 22-25, necessitating custom implementations for exception-based error mapping.

Key source files include:

- [`ErrorCodeHandler.java`](https://github.com/apache/linkis/blob/main/ErrorCodeHandler.java) – Base interface with common constants
- [`ExceptionErrorCodeHandler.java`](https://github.com/apache/linkis/blob/main/ExceptionErrorCodeHandler.java) – Interface for exception handling
- [`LinkisErrorCodeHandler.java`](https://github.com/apache/linkis/blob/main/LinkisErrorCodeHandler.java) – Default implementation with stub exception handling

## Step 1: Define Engine-Specific Error Codes

Create an enum implementing `org.apache.linkis.common.errorcode.LinkisErrorCode` to define your engine's error code taxonomy. This mirrors existing implementations like `EngineconnCoreErrorCodeSummary` found in [`linkis-computation-governance/linkis-engineconn/linkis-engineconn-plugin-core/src/main/java/org/apache/linkis/manager/engineplugin/errorcode/EngineconnCoreErrorCodeSummary.java`](https://github.com/apache/linkis/blob/main/linkis-computation-governance/linkis-engineconn/linkis-engineconn-plugin-core/src/main/java/org/apache/linkis/manager/engineplugin/errorcode/EngineconnCoreErrorCodeSummary.java).

```java
package org.apache.linkis.myengine.errorcode;

import org.apache.linkis.common.errorcode.LinkisErrorCode;

public enum MyEngineErrorCode implements LinkisErrorCode {
    ENGINE_START_FAILURE(20001, "Failed to start MyEngine instance"),
    ENGINE_TIMEOUT(20002, "MyEngine execution timed out after {0} ms"),
    INVALID_QUERY_SYNTAX(20003, "Query syntax error: {0}");

    private final int errorCode;
    private final String errorDesc;

    MyEngineErrorCode(int errorCode, String errorDesc) {
        this.errorCode = errorCode;
        this.errorDesc = errorDesc;
    }

    @Override
    public int getErrorCode() { return errorCode; }

    @Override
    public String getErrorDesc() { return errorDesc; }
}

```

## Step 2: Implement the ExceptionErrorCodeHandler Interface

Create a handler class that implements `ExceptionErrorCodeHandler` and overrides the `handle(Throwable t)` method. This method inspects exception types and returns the appropriate `LinkisErrorCode` enum value, or `null` to allow fallback to other handlers.

```java
package org.apache.linkis.myengine.errorhandler;

import org.apache.linkis.errorcode.client.handler.ExceptionErrorCodeHandler;
import org.apache.linkis.myengine.errorcode.MyEngineErrorCode;
import org.apache.linkis.myengine.exception.MyEngineException;
import org.apache.linkis.common.errorcode.LinkisErrorCode;

public class MyEngineExceptionHandler implements ExceptionErrorCodeHandler {

    @Override
    public LinkisErrorCode handle(Throwable t) {
        if (t instanceof MyEngineException) {
            String msg = t.getMessage();
            if (msg != null && msg.contains("timeout")) {
                return MyEngineErrorCode.ENGINE_TIMEOUT;
            } else if (msg != null && msg.contains("syntax")) {
                return MyEngineErrorCode.INVALID_QUERY_SYNTAX;
            } else {
                return MyEngineErrorCode.ENGINE_START_FAILURE;
            }
        }
        // Fallback – let the default handler deal with it
        return null;
    }
}

```

## Step 3: Register and Wire the Custom Handler

You can integrate your handler either by replacing the factory singleton or through direct instantiation.

**Option A: Replace the Factory Handler**

Subclass `LinkisErrorCodeHandler` to create a composite that delegates to your custom handler first, then falls back to the default logic:

```java
import org.apache.linkis.errorcode.client.handler.LinkisErrorCodeHandler;
import org.apache.linkis.myengine.errorhandler.MyEngineExceptionHandler;

LinkisErrorCodeHandler customHandler = new LinkisErrorCodeHandler() {
    private final MyEngineExceptionHandler engineHandler = new MyEngineExceptionHandler();

    @Override
    public LinkisErrorCode handle(Throwable t) {
        LinkisErrorCode code = engineHandler.handle(t);
        return code != null ? code : super.handle(t);
    }
};

```

**Option B: Direct Usage**

Instantiate and invoke the handler directly within your engine execution logic:

```java
MyEngineExceptionHandler handler = new MyEngineExceptionHandler();

try {
    // engine execution logic
} catch (Throwable e) {
    LinkisErrorCode code = handler.handle(e);
    if (code != null) {
        // process specific error code
    } else {
        // generic fallback handling
    }
}

```

## Step 4: Integrate with Engine Execution

In your engine's execution driver, catch exceptions and delegate to the custom handler to translate them into structured error codes consumable by the Linkis UI or REST API.

```java
public class MyEngineExecutor {
    private final MyEngineExceptionHandler errHandler = new MyEngineExceptionHandler();

    public void execute(String sql) {
        try {
            // actual engine execution logic
        } catch (Throwable t) {
            LinkisErrorCode code = errHandler.handle(t);
            if (code != null) {
                System.out.println("Engine error: " + code.getErrorCode() + " - " + code.getErrorDesc());
            } else {
                System.out.println("Unknown error: " + t.getMessage());
            }
        }
    }
}

```

## Key Source Files for Reference

- [`linkis-public-enhancements/linkis-pes-client/src/main/java/org/apache/linkis/errorcode/client/handler/ErrorCodeHandler.java`](https://github.com/apache/linkis/blob/main/linkis-public-enhancements/linkis-pes-client/src/main/java/org/apache/linkis/errorcode/client/handler/ErrorCodeHandler.java) – Base handler interface
- [`linkis-public-enhancements/linkis-pes-client/src/main/java/org/apache/linkis/errorcode/client/handler/ExceptionErrorCodeHandler.java`](https://github.com/apache/linkis/blob/main/linkis-public-enhancements/linkis-pes-client/src/main/java/org/apache/linkis/errorcode/client/handler/ExceptionErrorCodeHandler.java) – Exception-specific handler interface
- [`linkis-public-enhancements/linkis-pes-client/src/main/java/org/apache/linkis/errorcode/client/handler/LinkisErrorCodeHandler.java`](https://github.com/apache/linkis/blob/main/linkis-public-enhancements/linkis-pes-client/src/main/java/org/apache/linkis/errorcode/client/handler/LinkisErrorCodeHandler.java) – Default implementation with stub exception handling
- [`linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/errorcode/LinkisErrorCode.java`](https://github.com/apache/linkis/blob/main/linkis-commons/linkis-common/src/main/java/org/apache/linkis/common/errorcode/LinkisErrorCode.java) – Common error code representation
- [`linkis-computation-governance/linkis-engineconn/linkis-engineconn-plugin-core/src/main/java/org/apache/linkis/manager/engineplugin/errorcode/EngineconnCoreErrorCodeSummary.java`](https://github.com/apache/linkis/blob/main/linkis-computation-governance/linkis-engineconn/linkis-engineconn-plugin-core/src/main/java/org/apache/linkis/manager/engineplugin/errorcode/EngineconnCoreErrorCodeSummary.java) – Example engine error code enum

## Summary

- **Define** engine-specific error codes by creating an enum implementing `LinkisErrorCode`.
- **Implement** the `ExceptionErrorCodeHandler` interface to translate engine exceptions into structured error codes.
- **Register** your handler by subclassing `LinkisErrorCodeHandler` or using direct instantiation in the execution path.
- **Return** `null` from your handler for unrecognized exceptions to enable fallback to default handlers.
- **Integrate** the handler in your engine's execution driver to map failures to standardized error responses.

## Frequently Asked Questions

### What is the difference between ExceptionErrorCodeHandler and LogErrorCodeHandler?

`ExceptionErrorCodeHandler` processes Java `Throwable` objects directly at runtime, making it suitable for engine-specific exception mapping. `LogErrorCodeHandler` and `LogFileErrorCodeHandler` parse string log output or log files to extract error codes using pattern matching, which is useful for post-hoc analysis of engine logs.

### Why does the default LinkisErrorCodeHandler return null for exceptions?

The default `LinkisErrorCodeHandler.handle(Throwable)` method is implemented as a stub returning `null` in [`LinkisErrorCodeHandler.java`](https://github.com/apache/linkis/blob/main/LinkisErrorCodeHandler.java) at lines 22-25. This design forces developers to implement custom `ExceptionErrorCodeHandler` classes for engine-specific error mapping while preserving the existing log-parsing functionality.

### Can I use multiple ExceptionErrorCodeHandler implementations?

Yes. You can chain multiple handlers by checking for `null` return values and delegating to the next handler in sequence. When subclassing `LinkisErrorCodeHandler`, call `super.handle(t)` after your custom logic to maintain fallback to the default log-based error detection.

### How do I expose error codes through the Linkis REST API?

Use `LinkisErrorCodeClient` built via `ErrorCodeClientBuilder` to send mapped error codes to the Linkis error-code REST API. After obtaining an `ErrorCode` from your handler, instantiate the client and call `getErrorCodeByCode()` to retrieve detailed error information for client responses.