> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tensorlake.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Error handling

> How errors propagate in Tensorlake Applications — function exceptions, timeouts, retries, and patterns for building resilient agentic workflows.

Agentic applications interact with unreliable dependencies (LLMs, tools, external APIs). This guide explains how errors propagate in Tensorlake Applications and common patterns for building resilient workflows on the Agentic Runtime.

## How failures propagate

* **A function can fail** by raising an exception or timing out (see [Timeouts](/applications/timeouts)).
* **If an exception is not handled**, it bubbles up to the caller and can fail the overall request. Failed requests can be re-run with the [Replay API](/applications/durability#request-replay-api), and previously successful nested calls are served from [checkpoints](/applications/durability) instead of re-executing.
* **Retries** can be configured per-function or at the application level. See [Retries & Rate Limits](/applications/retries).
* **Mid-loop crashes** in long-running agents are covered in [Crash Recovery](/applications/crash-recovery).

## Pattern: catch errors and continue

Use `try/except` inside your application to decide whether to fail the request or degrade gracefully.

```python theme={null}
from tensorlake.applications import application, function

@function()
def call_tool(x: str) -> str:
    # e.g., LLM/tool/API call that can fail
    raise RuntimeError("tool failed")

@application()
@function()
def workflow(user_input: str) -> dict:
    try:
        tool_output = call_tool(user_input)
        return {"status": "ok", "tool_output": tool_output}
    except Exception as e:
        # Decide how your agent/workflow should behave on failure
        return {"status": "degraded", "error": str(e)}
```

## Pattern: retries for flaky dependencies

Retries are a good fit for transient failures (timeouts, 429s, temporary upstream errors). Configure them on the function (or set defaults on the application).

```python theme={null}
from tensorlake.applications import function, Retries

@function(retries=Retries(max_retries=3))
def flaky_step() -> str:
    ...
```

## Futures: handling parallel failures

When using [Futures](/applications/futures), errors are raised when you call `.result()`:

```python theme={null}
from tensorlake.applications import application, function, Future

@function()
def maybe_fails() -> str:
    raise RuntimeError("boom")

@application()
@function()
def parallel_work() -> str:
    fut: Future = maybe_fails.future().run()
    try:
        return fut.result()
    except Exception as e:
        return f"handled: {e}"
```

## Debugging tips

* **Start by reproducing locally**: Tensorlake Applications run as normal Python functions locally. See [Testing locally](/applications/quickstart#testing-locally).
* **Add structured logs**: log inputs/outputs (excluding secrets) so you can diagnose failures.
* **Make side effects idempotent**: if a function can retry, avoid double-charging or double-writing.

## Related Guides

<CardGroup cols={2}>
  <Card title="Retries & Rate Limits" icon="rotate" href="/applications/retries">
    Configure auto-retries for transient failures and structured-output validation.
  </Card>

  <Card title="Crash Recovery" icon="shield-check" href="/applications/crash-recovery">
    Resume long agent loops from the failed step instead of restarting.
  </Card>

  <Card title="Durable Execution" icon="clock-rotate-left" href="/applications/durability">
    Replay API, adaptive vs. strict modes, and how checkpoints survive failures.
  </Card>

  <Card title="Timeouts" icon="clock" href="/applications/timeouts">
    Per-function deadlines and progress-update heartbeats.
  </Card>
</CardGroup>
