:title
13. Errors and testing

:content
Capy reports type and syntax errors before a unit runs. Runtime failures include the original Capy source location.

## Handle expected missing data

Use a fallback when absence is valid:

:example capy render
function display_name(profile : dval) string
{
	-> string(profile.name, fallback: "guest")
}

function RENDER()
{
	print(display_name({}), "\n")
}

:output
guest

:content
The fallback handles both `none` and failed string conversion. It does not hide a compiler error or an unrelated runtime trap.

## Compiler errors

The compiler rejects invalid syntax, unknown names, and incompatible types. For example, this assignment is invalid:

```capy-error
function RENDER()
{
	var count := 1
	count = "one"
}
```

`count` has type `s64`. Assignment cannot change its type to `string`.

Read the first diagnostic and its source location. Later messages can be consequences of the first error.

## See compiler errors in the browser

Set this option in `/etc/bearer/settings.cfg` to show compiler diagnostics on the runtime error page:

```ini
SHOW_DYNAMIC_COMPILE_ERRORS=1
```

A compile failure stops the request and returns HTTP 500. This applies to entry units, components, `unit_call()`, imported aliases, and units loaded with `unit_load()`.

The unit configured by `page_runtime_error` receives the error in `request.call.error`. A compile error has these fields:

- `type` is `compile_error`.
- `unit` is the resolved unit path.
- `compiler_messages` contains the full compiler output.
- `location.file`, `location.line`, and `location.column` identify the first diagnostic.
- `title` and `details` contain a summary for existing error handlers.

Set `SHOW_DYNAMIC_COMPILE_ERRORS=0` to hide source diagnostics. The error still contains `type`, `unit`, `title`, and `details`.

Nginx can replace Bearer's error response when error interception is active. Keep interception off in the FastCGI location:

```nginx
fastcgi_intercept_errors off;
```

## Runtime traps

Use strict access when missing data violates the program contract:

:example capy cli
function RENDER()
{
	var profile := {}
	if !has(profile, "name")
	{
		trap()
	}
	var name := get(profile, "name")
	print(name)
}

:content

This traps if `name` is missing or the access path is unusable. Other traps include division by zero, invalid typed-array indexes, failed host operations, and an explicit `trap()`.

Do not use a fallback for data that the program requires. A clear trap at the boundary is safer than incorrect work with a fabricated value.

## Test through Bearer

Run one page through the local CLI socket:

```text
scripts/bearer-cli /path/to/page.capy
```

The CLI helper exposes the response body and runtime errors. Use an HTTP client or a repository HTTP test helper when a test must verify status and headers. Include failure cases for missing input, invalid conversions, and boundary errors.

The repository test suites exercise the compiler, Wasm runtime, source maps, components, units, tasks, and documentation examples:

```text
scripts/test_capy_native.sh
scripts/test_capy_phase1.sh
scripts/test_capy_reference.sh
```

Run the focused test while editing. Run the broader gate before deployment.

## Keep code direct

Prefer a small typed helper over repeated dynamic conversion. Keep request parsing near the request boundary. Convert a `dval` to a static type once the required shape is known.

Use one name for one thing. Remove wrappers that only rename another function. Keep comments for behavior that the code cannot make clear.

## Find API details

The language guide explains how Capy code fits together. The API reference gives exact standard-library signatures and failure behavior. Use the generated Capy signature on each API page.

## Read failures as contracts

A compile error usually means the source does not match the type contract. Fix that error before you inspect later messages.

A runtime trap usually means the input did not match the application contract. Test required data with `has()` before you call `get()`. Use constructors with fallbacks when absence is valid.

Write tests for both paths. A success test proves the expected shape works. A failure test proves bad input cannot silently continue.

:see-group
guides

:see
capy-08-dynamic-values
capy-09-web-handlers-and-requests
trap
