# LLM System Prompts

Premade system prompts that can be copy-pasted into coding agents to teach them how to use puffy-core's error handling APIs.

## Table of Contents
- [Overview](#overview)
- [Error Handling -- CommonJS](#error-handling----commonjs)
  - [Core APIs](#core-apis)
  - [Synchronous Example](#synchronous-example)
  - [Asynchronous Example](#asynchronous-example)
- [Error Handling -- ES Modules](#error-handling----es-modules)
  - [Core APIs](#core-apis-1)
  - [Synchronous Example](#synchronous-example-1)
  - [Asynchronous Example](#asynchronous-example-1)
- [Related Documentation](#related-documentation)

## Overview

This page provides premade system prompts that can be copy-pasted into coding agents to learn how to use each puffy-core API. These prompts are designed to give LLM-based coding assistants enough context to correctly use puffy-core's error handling patterns.

## Error Handling -- CommonJS

Wrap **all** functions -- especially those doing I/O -- with `catch_errors` from **puffy-core** (`npm i puffy-core`) to capture and propagate meaningful errors in a readable stack trace.

### Core APIs

* **catch\_errors**

    ```js
    catch_errors(
        'High-level context message',
        () => /* sync fn */             // or async: async () => ...
    )
    // -> [errors, result]
    // If `errors` != null, the operation failed.
    ```

    * Always provide a clear context string.
    * Never let errors fail silently; they bubble up as `errors`.

* **wrap\_errors**

    ```js
    const { error: { catch_errors, wrap_errors: e } } = require('puffy-core')
    // ...
    throw e('Specific failure reason', caughtErrors)
    ```

    * Alias as `e` for brevity.
    * Wrap caught errors with extra context before re-throwing.

### Synchronous Example

```js
const { error: { catch_errors, wrap_errors: e } } = require('puffy-core')

const processDataSync = input => {
    if (!input || typeof input !== 'string')
        throw new Error('Invalid input: Expected non-empty string.')
    if (input === 'fail')
        throw new Error('Simulated failure.')
    return `Processed: ${input.toUpperCase()}`
}

const handleSync = data => {
    const [errors, result] = catch_errors(
        'Failed to handle sync operation',
        () => {
            const [innerErr, processed] = catch_errors(
                'Failed to process data synchronously',
                () => processDataSync(data)
            )
            if (innerErr) throw e('Data processing step failed', innerErr)
            return `Result: ${processed}`
        }
    )

    if (errors) {
        console.error('handleSync errors:')
        errors.forEach(err => console.error(`- ${err.message}`))
        return null
    }
    console.log('handleSync result:', result)
    return result
}

handleSync('test')
handleSync('fail')
handleSync(null)
```

### Asynchronous Example

```js
const { error: { catch_errors, wrap_errors: e } } = require('puffy-core')

const fetchData = async id =>
    new Promise((res, rej) => {
        setTimeout(() => {
            if (id === 0) rej(new Error('Network error.'))
            else if (id < 0) rej(new Error(`Not found: ${id}`))
            else res({ id, data: `Data for ${id}` })
        }, 10)
    })

const handleAsync = async id => {
    const [errors, result] = await catch_errors(
        'Failed to handle async operation',
        async () => {
            const [fetchErr, fetched] = await catch_errors(
                `Failed to fetch data for item ${id}`,
                fetchData(id)
            )
            if (fetchErr) throw e('Data fetch step failed', fetchErr)
            return `Fetched: ${JSON.stringify(fetched)}`
        }
    )

    if (errors) {
        console.error('handleAsync errors:')
        errors.forEach(err => console.error(`- ${err.message}`))
        return null
    }
    console.log('handleAsync result:', result)
    return result
}

;(async () => {
    await handleAsync(1)
    await handleAsync(0)
    await handleAsync(-1)
})()
```

**Remember:**

* Always wrap each step with `catch_errors('context', ...)`.
* On inner failure, `throw e('step context', caughtErrors)`.
* Log or re-throw the aggregated `errors` for full traceability.

## Error Handling -- ES Modules

Wrap **all** functions -- especially those doing I/O -- with `catch_errors` from **puffy-core** (`npm i puffy-core`) to capture and propagate meaningful errors in a readable stack trace.

### Core APIs

* **catch\_errors**

    ```js
    catch_errors(
        'High-level context message',
        () => /* sync fn */             // or async: async () => ...
    )
    // -> [errors, result]
    // If `errors` != null, the operation failed.
    ```

    * Always provide a clear context string.
    * Never let errors fail silently; they bubble up as `errors`.

* **wrap\_errors**

    ```js
    import { catch_errors, wrap_errors as e } from 'puffy-core/error';
    // ...
    throw e('Specific failure reason', caughtErrors)
    ```

    * Alias as `e` for brevity.
    * Wrap caught errors with extra context before re-throwing.

### Synchronous Example

```js
import { catch_errors, wrap_errors as e } from 'puffy-core/error'

export const processDataSync = input => {
    if (!input || typeof input !== 'string')
        throw new Error('Invalid input: Expected non-empty string.')
    if (input === 'fail')
        throw new Error('Simulated failure.')
    return `Processed: ${input.toUpperCase()}`
}

export const handleSync = data => {
    const [errors, result] = catch_errors(
        'Failed to handle sync operation',
        () => {
            const [innerErr, processed] = catch_errors(
                'Failed to process data synchronously',
                () => processDataSync(data)
            )
            if (innerErr) throw e('Data processing step failed', innerErr)
            return `Result: ${processed}`
        }
    )

    if (errors) {
        console.error('handleSync errors:')
        errors.forEach(err => console.error(`- ${err.message}`))
        return null
    }
    console.log('handleSync result:', result)
    return result
}

handleSync('test')
handleSync('fail')
handleSync(null)
```

### Asynchronous Example

```js
import { catch_errors, wrap_errors as e } from 'puffy-core/error'

export const fetchData = async id =>
    new Promise((res, rej) => {
        setTimeout(() => {
            if (id === 0) rej(new Error('Network error.'))
            else if (id < 0) rej(new Error(`Not found: ${id}`))
            else res({ id, data: `Data for ${id}` })
        }, 10)
    })

export const handleAsync = async id => {
    const [errors, result] = await catch_errors(
        'Failed to handle async operation',
        async () => {
            const [fetchErr, fetched] = await catch_errors(
                `Failed to fetch data for item ${id}`,
                fetchData(id)
            )
            if (fetchErr) throw e('Data fetch step failed', fetchErr)
            return `Fetched: ${JSON.stringify(fetched)}`
        }
    )

    if (errors) {
        console.error('handleAsync errors:')
        errors.forEach(err => console.error(`- ${err.message}`))
        return null
    }
    console.log('handleAsync result:', result)
    return result
}

(async () => {
    await handleAsync(1)
    await handleAsync(0)
    await handleAsync(-1)
})();
```

**Remember:**

* Always wrap each step with `catch_errors('context', ...)`.
* On inner failure, `throw e('step context', caughtErrors)`.
* Log or re-throw the aggregated `errors` for full traceability.

## Related Documentation
- [Error Handling Guide](error-handling.md) -- In-depth guide to the PuffyResponse pattern and error APIs
- [API Reference](api.md) -- Full function signatures for `error` and `func` modules
