Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 30 additions & 1 deletion docs/develop/java/error-handling.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,33 @@ You can catch terminal errors, and build your control flow around it.

<Info>
When throwing a terminal error, undo earlier handler actions to keep the system consistent. See our [sagas guide](/guides/sagas) for details.
</Info>
</Info>

## Terminal error metadata

You can attach a metadata map to a `TerminalException` to propagate structured context to callers.
This requires Restate Server >= 1.6.

<CodeGroup>
```java Java {"CODE_LOAD::java/src/main/java/develop/ErrorHandling.java#metadata"}
throw new TerminalException(
"Something went wrong", Map.of("correlationId", correlationId));
```
```kotlin Kotlin {"CODE_LOAD::kotlin/src/main/kotlin/develop/ErrorHandling.kt#metadata"}
throw TerminalException(
"Something went wrong", mapOf("correlationId" to correlationId))
```
</CodeGroup>

The metadata is propagated to callers and accessible via `getMetadata()` / `.metadata`:

<CodeGroup>
```java Java {"CODE_LOAD::java/src/main/java/develop/ErrorHandling.java#catch_metadata"}
Map<String, String> metadata = e.getMetadata();
String correlationId = metadata.get("correlationId");
```
```kotlin Kotlin {"CODE_LOAD::kotlin/src/main/kotlin/develop/ErrorHandling.kt#catch_metadata"}
val metadata = e.metadata
val correlationId = metadata["correlationId"]
```
</CodeGroup>
49 changes: 49 additions & 0 deletions docs/services/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,55 @@ if err := server.NewRestate().
```
</CodeGroup>

### Spring Boot configuration (Java/Kotlin)

If you use the Spring Boot integration, you can configure services via `application.properties` or `application.yml` without modifying code.

**Per-service configuration:**

```properties application.properties
# Configuration for a service named "MyService"
restate.components.MyService.inactivity-timeout=10m
restate.components.MyService.abort-timeout=1m
restate.components.MyService.idempotency-retention=7d
restate.components.MyService.journal-retention=1d
restate.components.MyService.ingress-private=false
restate.components.MyService.enable-lazy-state=true
restate.components.MyService.documentation=My service description
restate.components.MyService.metadata.version=1.0
restate.components.MyService.retry-policy.initial-interval=100ms
restate.components.MyService.retry-policy.exponentiation-factor=2.0
restate.components.MyService.retry-policy.max-interval=10s
restate.components.MyService.retry-policy.max-attempts=10
restate.components.MyService.retry-policy.on-max-attempts=PAUSE

# Per-handler configuration
restate.components.MyService.handlers.myHandler.inactivity-timeout=5m
restate.components.MyService.handlers.myHandler.ingress-private=true
```

**Global defaults (since SDK v2.7.0):**

Top-level `restate.*` properties act as defaults for all registered services.
Per-service `restate.components.<Name>.*` properties override them on a per-service basis:

```properties application.properties
# Applied to all services by default
restate.journal-retention=PT48H
restate.inactivity-timeout=PT10M
restate.retry-policy.max-attempts=5

# Overrides just for MyService
restate.components.MyService.journal-retention=PT72H
restate.components.MyService.ingress-private=true
```

Supported global defaults: `documentation`, `metadata`, `inactivity-timeout`, `abort-timeout`, `idempotency-retention`, `workflow-retention`, `journal-retention`, `ingress-private`, `enable-lazy-state`, `retry-policy`.

<Note>
The `executor` property is global-only and configured via `restate.executor` (Java only).
</Note>

### Override configuration

You can override the service options configured in your code via the UI or CLI.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,22 @@ Note: the Java SDK uses `TerminalException`, NOT `TerminalError` (which is used

Any other exception type causes automatic retries with exponential backoff. For retry policy configuration, refer to the retry guide.

### TerminalException metadata

You can attach a string metadata map to a `TerminalException`. The metadata is propagated to callers and accessible via `getMetadata()`. Requires Restate Server >= 1.6.

```java
throw new TerminalException(
"Something went wrong", Map.of("correlationId", correlationId));
```

Callers can read the metadata:

```java
Map<String, String> metadata = e.getMetadata();
String correlationId = metadata.get("correlationId");
```

---

## SDK Clients (External Invocations)
Expand Down
12 changes: 12 additions & 0 deletions restate-plugin/src/references/java/api-and-pitfalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,18 @@ Note: the Java SDK uses `TerminalException`, NOT `TerminalError` (which is used

Any other exception type causes automatic retries with exponential backoff. For retry policy configuration, refer to the retry guide.

### TerminalException metadata

You can attach a string metadata map to a `TerminalException`. The metadata is propagated to callers and accessible via `getMetadata()`. Requires Restate Server >= 1.6.

```java {"CODE_LOAD::java/src/main/java/develop/ErrorHandling.java#metadata"}
```

Callers can read the metadata:

```java {"CODE_LOAD::java/src/main/java/develop/ErrorHandling.java#catch_metadata"}
```

---

## SDK Clients (External Invocations)
Expand Down
21 changes: 21 additions & 0 deletions snippets/java/src/main/java/develop/ErrorHandling.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import dev.restate.sdk.Context;
import dev.restate.sdk.common.TerminalException;
import java.util.Map;

public class ErrorHandling {

Expand All @@ -12,4 +13,24 @@ public void errorHandling(Context ctx) {
// <end_here>

}

public void errorHandlingWithMetadata(Context ctx, String correlationId) {

// <start_metadata>
throw new TerminalException(
"Something went wrong", Map.of("correlationId", correlationId));
// <end_metadata>

}

public void catchMetadata(Context ctx) {
try {
// ... some operation
} catch (TerminalException e) {
// <start_catch_metadata>
Map<String, String> metadata = e.getMetadata();
String correlationId = metadata.get("correlationId");
// <end_catch_metadata>
}
}
}
18 changes: 18 additions & 0 deletions snippets/kotlin/src/main/kotlin/develop/ErrorHandling.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,22 @@ class ErrorHandling {
throw TerminalException(500, "Something went wrong")
// <end_here>
}

fun errorHandlingWithMetadata(ctx: Context, correlationId: String) {
// <start_metadata>
throw TerminalException(
"Something went wrong", mapOf("correlationId" to correlationId))
// <end_metadata>
}

fun catchMetadata(ctx: Context) {
try {
// ... some operation
} catch (e: TerminalException) {
// <start_catch_metadata>
val metadata = e.metadata
val correlationId = metadata["correlationId"]
// <end_catch_metadata>
}
}
}
Loading