> This page is for version 0.4.0.
> For other versions, use one of these documentation indexes:
> - Main (default): https://docs.nvidia.com/nemo/gym/main/llms.txt
> - 0.7.0: https://docs.nvidia.com/nemo/gym/v0.7.0/llms.txt
> - 0.6.0: https://docs.nvidia.com/nemo/gym/v0.6.0/llms.txt
> - 0.5.1: https://docs.nvidia.com/nemo/gym/v0.5.1/llms.txt
> - 0.5.0: https://docs.nvidia.com/nemo/gym/v0.5.0/llms.txt
> - 0.4.0: https://docs.nvidia.com/nemo/gym/v0.4.0/llms.txt
> - 0.3.0: https://docs.nvidia.com/nemo/gym/v0.3.0/llms.txt
> - 0.2.1: https://docs.nvidia.com/nemo/gym/v0.2.1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.nvidia.com/nemo/gym/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.nvidia.com/nemo/gym/_mcp/server.

# nemo_gym.utils.exception_inspection

Read facts from any Python exception: its explicit causes, its type name and its HTTP status.

These functions know nothing about Gym's failure types; `nemo_gym.core.typed_exceptions` builds on them.

## Module Contents

### Functions

| Name                                                                                    | Description                                                                                                 |
| --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| [`bounded_text`](#nemo_gym-utils-exception_inspection-bounded_text)                     | `text`, or its start with `TRUNCATION_MARKER` when it is longer than `max_chars`.                           |
| [`error_to_http_status`](#nemo_gym-utils-exception_inspection-error_to_http_status)     | The HTTP status `error` carries as an int: `status` (aiohttp), `status_code` (FastAPI, SDKs) or             |
| [`explicit_causes`](#nemo_gym-utils-exception_inspection-explicit_causes)               | `error` and then each `__cause__` (`raise ... from`), outermost first.                                      |
| [`provider_error_reason`](#nemo_gym-utils-exception_inspection-provider_error_reason)   | The provider's own code for an SDK error (OpenSandbox's `error.code`, e.g. `SANDBOX::ENDED`), else the      |
| [`qualified_type_name`](#nemo_gym-utils-exception_inspection-qualified_type_name)       | `module.QualName` of `error`'s type; a builtin type is its bare name.                                       |
| [`sandbox_failure_prefix`](#nemo_gym-utils-exception_inspection-sandbox_failure_prefix) | `[sandbox phase=... provider=... sandbox=... reason=... http=... exit=... signal=... command=...] `: what a |

### Data

[`TRUNCATION_MARKER`](#nemo_gym-utils-exception_inspection-TRUNCATION_MARKER)

### API

```python
nemo_gym.utils.exception_inspection.bounded_text(
    text: str,
    max_chars: int
) -> str
```

`text`, or its start with `TRUNCATION_MARKER` when it is longer than `max_chars`.

```python
nemo_gym.utils.exception_inspection.error_to_http_status(
    error: BaseException
) -> int | None
```

The HTTP status `error` carries as an int: `status` (aiohttp), `status_code` (FastAPI, SDKs) or
`http_status` (Gym); `None` when it carries none.

```python
nemo_gym.utils.exception_inspection.explicit_causes(
    error: BaseException
) -> collections.abc.Iterator[BaseException]
```

`error` and then each `__cause__` (`raise ... from`), outermost first.

`__context__` (an exception that was only being handled, such as a retry's earlier attempt) is not a
cause and is not followed. A cycle stops the walk.

```python
nemo_gym.utils.exception_inspection.provider_error_reason(
    error: BaseException
) -> str
```

The provider's own code for an SDK error (OpenSandbox's `error.code`, e.g. `SANDBOX::ENDED`), else the
error's type name.

```python
nemo_gym.utils.exception_inspection.qualified_type_name(
    error: BaseException
) -> str
```

`module.QualName` of `error`'s type; a builtin type is its bare name.

```python
nemo_gym.utils.exception_inspection.sandbox_failure_prefix(
    phase: str,
    provider: str | None = None,
    sandbox_id: str | None = None,
    reason: str | None = None,
    http_status: int | None = None,
    exit_code: int | None = None,
    signal: str | None = None,
    command: str | None = None
) -> str
```

`[sandbox phase=... provider=... sandbox=... reason=... http=... exit=... signal=... command=...] `: what a
producer knows about a sandbox failure, as a fixed-order prefix of its `failure_reason`, so a saved record says
in which phase, on which sandbox and with which provider status it failed. Unknown facts are left out; each value
is one bounded token. It decides nothing: no reader classifies a failure from it.

```python
nemo_gym.utils.exception_inspection.TRUNCATION_MARKER = ' [truncated]'
```