# `MishkaCmsCore.Runtime.Compilers.ErrorCompiler`
[🔗](https://github.com/mishka-group/mishka_cms_core/blob/v0.0.1/lib/mishka_cms_core/runtime/compilers/error_compiler.ex#L5)

Runtime compiler for Error Page modules with dynamic content compilation.

This module provides functionality to dynamically compile error page modules at runtime
from configuration data. It generates complete error handling modules with custom layouts,
templates, and helper functions for different HTTP error status codes.

## Features

- Dynamic error page module generation from configuration
- Custom error page templates for different HTTP status codes
- Flexible layout system with root layout and per-status layouts
- Helper function integration for custom error page logic
- Automatic CSS and JavaScript injection for styled error pages
- Fallback error handling for unhandled status codes
- Site-specific error page configurations

## Error Page Structure

Generated error page modules include:
- `__error_information__/0` - Returns error page metadata
- `__error_information__/1` - Returns specific metadata by key
- `render/2` - Main rendering function for each status code
- `layout/2` - Layout function for each status code
- `root_layout/1` - Root HTML layout wrapper
- Helper functions (if defined)

## Usage

    params = %{
      title: "My Site Errors",
      error_module: MyApp.Errors.SiteErrors,
      site: "main",
      site_id: 1,
      error_pages: [
        %{
          status: 404,
          template: ~S(<h1>Page Not Found</h1><p>The page you're looking for doesn't exist.</p>),
          layout: %{template: ~S(<div class="error-layout"><%= @inner_content %></div>)}
        },
        %{
          status: 500,
          template: ~S(<h1>Server Error</h1><p>Something went wrong on our end.</p>)
        }
      ],
      root_layout_template: ~S(
        <!DOCTYPE html>
        <html>
          <head><title>Error <%= @status %></title></head>
          <body><%= @inner_content %></body>
        </html>
      ),
      helpers: [
        %{
          name: "format_error_message",
          args: "status, message",
          code: ~S("Error " <> Integer.to_string(status) <> ": " <> message)
        }
      ]
    }

    ast = ErrorCompiler.build_module(params)
    MishkaCmsCore.Runtime.Compilers.ModuleCompiler.compile_module(ast)

## Layout Hierarchy

The error page rendering follows this hierarchy:
1. **Root Layout** - Outer HTML document structure
2. **Status Layout** - Per-status layout wrapper (optional)
3. **Error Template** - The actual error content

## Error Page Configuration

Each error page in the `:error_pages` list should contain:
- `:status` - HTTP status code, or `:offline` for the page an offline site shows (required) —
  see `MishkaCmsCore.Runtime.ErrorStatus`
- `:template` - Error content template (required)
- `:layout` - Optional layout wrapper with `:template` key

# `build_error_information`

Build error page information including metadata.

Creates AST for the `__error_information__` functions that provide access to error page
metadata, private information, and extra data. These functions are used by the runtime
system to introspect error page properties.

## Parameters

- `params` - Atomized error page parameters map

## Returns

Returns a tuple `{params, functions_ast}` where `functions_ast` contains the AST for:
- `__error_information__/0` - Returns complete metadata map
- `__error_information__/1` - Returns metadata by atom key or key path
- `__error_information__/1` - Returns metadata by string dot-notation path

## Metadata Structure

The metadata includes:
- `:error` - Public error page info (title, path, error_pages, timestamp)
- `:private` - Private runtime info (id, error_module, priority, site details)
- `:extra` - Additional custom metadata

# `build_helpers`

Build helper functions for the error pages.

Processes helper function definitions and creates corresponding function AST, plus
generates the root layout function for the complete HTML document structure.

## Parameters

- `{params, functions_ast}` - Tuple containing params and accumulated AST functions

## Returns

Returns updated tuple with helper functions and root layout function added to the AST.

## Helper Functions

Each helper function definition should contain:
- `:name` - Function name as string
- `:args` - Function arguments as Elixir code string
- `:code` - Function body as Elixir code string

## Root Layout Function

Generates a `root_layout/1` function that provides the outer HTML document structure:

### Custom Root Layout
If `:root_layout_template` is provided, compiles it as the root layout.

### Default Root Layout
If no custom template provided, generates a default HTML document with:
- Proper DOCTYPE and HTML structure
- Error status in page title
- CSRF token meta tag
- Viewport meta tag for responsive design
- Automatic CSS injection from TailwindCompiler (if site configured)
- Automatic JavaScript injection from JavaScriptCompiler (if site configured)
- Body containing the inner content

## Template Compilation

All templates are compiled using Phoenix.HTML.Engine for proper HTML generation
and security (XSS protection, HTML escaping, etc.).

# `build_layout_functions`

Build layout functions for error pages.

Generates layout functions for each error page status code. Layout functions provide
an intermediate rendering layer between the error template and the root layout.

## Parameters

- `{params, functions_ast}` - Tuple containing params and accumulated AST functions

## Returns

Returns updated tuple with layout functions added for each status code.

## Generated Functions

For each error page, generates a `layout/2` function that:
- Takes a status code and assigns map as parameters
- Returns the rendered layout template (if provided)
- Falls back to returning inner_content directly if no layout template

## Layout Behavior

- **With layout template**: Renders the template with inner_content available
- **Without layout template**: Returns the inner_content as-is for direct rendering

# `build_module`

Main function to build error page modules from error page data.

Takes error page configuration parameters and returns a complete AST for an error handling module.
The function orchestrates the entire compilation process through a pipeline of transformations.

## Parameters

- `params` - Map containing error page configuration with keys:
  - `:title` - Error page title/name (required)
  - `:error_module` - Target module name (required)
  - `:site` - Site identifier (required)
  - `:site_id` - Site ID for database reference
  - `:error_pages` - List of error page definitions (required)
  - `:root_layout_template` - Root HTML layout template (optional)
  - `:helpers` - List of helper function definitions (optional)
  - `:host` - Host information for multi-tenant setups
  - `:extra` - Additional metadata

## Error Page Structure

Each error page in `:error_pages` should contain:
- `:status` - HTTP status code (integer)
- `:template` - Error content template string
- `:layout` - Optional layout map with `:template` key

## Returns

Returns the complete AST for the error module that can be compiled using
`MishkaCmsCore.Runtime.Compilers.ModuleCompiler.compile_module/1`.

## Example

    params = %{
      title: "Site Error Pages",
      error_module: MyApp.SiteErrors,
      site: "production",
      error_pages: [
        %{status: 404, template: "<h1>Not Found</h1>"},
        %{status: 500, template: "<h1>Server Error</h1>"}
      ]
    }

    ast = build_module(params)

# `build_render_functions`

Build render functions for error pages.

Generates the main rendering functions for each error page status code and a catch-all
fallback function. These functions are the primary entry points for error page rendering.

## Parameters

- `{params, functions_ast}` - Tuple containing params and accumulated AST functions

## Returns

Returns updated tuple with render functions added for each status code plus a catch-all function.

## Generated Functions

For each error page, generates a `render/2` function that:
1. Takes a connection and status code as parameters
2. Creates assigns with conn, status, and inner_content
3. Calls the appropriate layout function for the status
4. Wraps the result in the root layout

## Catch-All Function

Adds a fallback `render/2` function that:
- Handles any unhandled status codes
- Logs a warning about the missing error page
- Returns a plain text status phrase using `Plug.Conn.Status.reason_phrase/1`

## Rendering Flow

1. `render/2` called with conn and status
2. Error template compiled and rendered
3. Layout template applied (if configured)
4. Root layout wraps the final result

# `create_module_ast`

Create the final module AST.

Assembles all error page components into a complete error handling module AST.
The generated module includes all necessary imports and uses for proper Phoenix integration.

## Parameters

- `{params, functions_ast}` - Tuple containing params and all accumulated function ASTs

## Returns

Returns the complete module AST ready for compilation via `ModuleCompiler.compile_module/1`.

## Generated Module Structure

The final module includes:
- `defmodule` declaration with the target error module name
- Required imports (`Logger`)
- LiveView integration via the configured `:web_module`
- Runtime component helper imports
- All accumulated function definitions (info, layout, render, helpers, root layout)

The module is fully self-contained and ready for runtime compilation and loading
into the Phoenix error handling system.

# `fallback_title`

```elixir
@spec fallback_title(MishkaCmsCore.Runtime.ErrorStatus.t()) :: String.t()
```

The `<title>` of an error page whose site set no root layout, in the language of the request.

# `make_env`

Create environment for template compilation.

Builds a compilation environment with necessary imports for template processing.
Ensures that Phoenix HTML, Component, and LiveView helpers are available during
template compilation.

## Returns

Returns a `Macro.Env` struct with all required imports defined for proper template compilation.

## Imported Modules

- `Phoenix.HTML` - HTML generation helpers and security functions
- `Phoenix.Component` - Component helpers and sigil_H support

Failed imports are logged but don't stop the compilation process, ensuring robustness
even when some modules aren't available.

## Error Handling

If any module fails to import, the error is logged as a warning and compilation continues
with the remaining successfully imported modules.

# `offline_entry?`

```elixir
@spec offline_entry?(module()) :: boolean()
```

Whether the compiled Error Page `module` holds an `:offline` entry, however its status was stored.

# `render_page`

```elixir
@spec render_page(module(), Plug.Conn.t(), MishkaCmsCore.Runtime.ErrorStatus.t()) ::
  iodata()
```

The compiled Error Page `module`'s page for `status`, drawn for `conn`, as HTML.

The template is handed `@status`, and `@conn` with `:page_module` and `:page_data` assigned.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
