---
title: HandlerOutcome
description: "What a workload's hook handler did. Its output is in the daemon's log, not here."
---

```python
@final
class HandlerOutcome
```

What a workload's hook handler did. Its output is in the daemon's log, not here.

## Constructor

`HandlerOutcome` declares no `__new__` or `__init__`, so it is not constructed directly: an instance comes back from another call in this package.

## Properties

### `duration_ms`

```python
duration_ms: int
```

Milliseconds from spawn to exit or kill.

### `error`

```python
error: str | None
```

Why it could not run at all, such as `not executable`.

### `exit_code`

```python
exit_code: int | None
```

The exit code, or `None` when the handler was killed or never started.

### `signal`

```python
signal: int | None
```

The signal that ended it, if one did.

### `succeeded`

```python
succeeded: bool
```

Whether it ran and exited 0 within its budget.

### `timed_out`

```python
timed_out: bool
```

Whether the daemon killed it at its time budget.

## Special methods

### `__repr__`

```python
def __repr__() -> str
```

## Provenance

This page is generated from `bindings/microvms-py/microvms.pyi` by Griffe 2.3.0, run from `site/scripts/gen-reference.mjs` on every `pnpm run sync`, so an edit made here is overwritten by the next run.

To change the page, change the doc comment in the binding's Rust source, then regenerate the declarations with `mise run stubs`. `mise run stubs:check` fails when the committed file no longer matches the source.