> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/charlietyn/openapi-generator/llms.txt
> Use this file to discover all available pages before exploring further.

# Exceptions

> Exception types and error handling in the OpenAPI generator

## Overview

The Laravel OpenAPI Generator raises standard PHP and Laravel exceptions for invalid input, missing configuration, and generation errors. Understanding these exceptions helps you implement robust error handling in your application.

<Note>
  The package does not define custom exception classes. It uses PHP's built-in `InvalidArgumentException` and generic `Exception` for error conditions.
</Note>

***

## Exception Types

### InvalidArgumentException

Thrown when invalid input is provided to generation methods.

**Exception Class:** `\InvalidArgumentException`

**Common Scenarios:**

1. **Invalid API Types**
2. **Invalid Environment Names**
3. **Disabled API Types**

***

## Invalid API Types

Thrown when a requested API type is unknown or disabled in configuration.

### Source Location

**Class:** `OpenApiServices`\
**Method:** `validateApiTypes()`\
**Location:** `src/Services/OpenApiServices.php:147-161`

**Code:**

```php theme={null}
private function validateApiTypes(?array $types): void
{
    if (empty($types)) {
        return;
    }

    $available = array_keys($this->getEnabledApiTypes());
    $invalid = array_diff($types, $available);

    if (!empty($invalid)) {
        throw new \InvalidArgumentException(
            'Unknown or disabled API types: ' . implode(', ', $invalid)
        );
    }
}
```

***

### When Thrown

**Programmatic API:**

```php theme={null}
use Ronu\OpenApiGenerator\Facades\OpenApiGenerator;

try {
    $spec = OpenApiGenerator::generate(
        apiTypes: ['invalid-type']
    );
} catch (\InvalidArgumentException $e) {
    // Handle: "Unknown or disabled API types: invalid-type"
    logger()->error('Invalid API type', ['error' => $e->getMessage()]);
}
```

**Artisan Command:**

```bash theme={null}
php artisan openapi:generate --api-type=invalid
```

**Output:**

```
❌ Failed to generate specification
Unknown or disabled API types: invalid. Available types: api, mobile, admin
```

**HTTP Controller:**

**Location:** `src/Controllers/OpenApiController.php:86-90`

```php theme={null}
catch (\InvalidArgumentException $e) {
    return response()->json([
        'error' => 'Invalid api_type parameter',
        'message' => $e->getMessage(),
    ], 422);
}
```

**HTTP Request:**

```bash theme={null}
curl "http://localhost:8000/documentation/openapi.json?api_type=invalid"
```

**HTTP Response (422):**

```json theme={null}
{
  "error": "Invalid api_type parameter",
  "message": "Unknown or disabled API types: invalid"
}
```

***

### Available API Types

To avoid this exception, use only enabled API types from your configuration:

```php theme={null}
// config/openapi.php
'api_types' => [
    'api' => [
        'prefix' => 'api',
        'enabled' => true,
    ],
    'mobile' => [
        'prefix' => 'mobile',
        'enabled' => true,
    ],
    'admin' => [
        'prefix' => 'admin',
        'enabled' => false, // This will trigger exception if requested
    ],
],
```

**Valid API types:** `api`, `mobile`\
**Invalid API types:** `admin` (disabled), `invalid` (doesn't exist)

***

## Invalid Environment Names

Thrown when a requested environment is not defined in configuration.

### Source Location

**Class:** `EnvironmentGenerator`\
**Method:** `getEnvironmentConfig()`\
**Location:** `src/Services/EnvironmentGenerator.php:120-131`

**Code:**

```php theme={null}
protected function getEnvironmentConfig(string $environmentName): array
{
    $envConfig = config("openapi.environments.{$environmentName}");

    if (!$envConfig) {
        throw new \InvalidArgumentException(
            "Environment '{$environmentName}' not found in config/openapi.php"
        );
    }

    return $envConfig;
}
```

***

### When Thrown

**Programmatic API:**

```php theme={null}
use Ronu\OpenApiGenerator\Facades\OpenApiGenerator;

try {
    $spec = OpenApiGenerator::generate(
        environment: 'staging' // Not defined in config
    );
} catch (\InvalidArgumentException $e) {
    // Handle: "Environment 'staging' not found in config/openapi.php"
}
```

**Artisan Command:**

The command validates and falls back to `artisan` with a warning:

```bash theme={null}
php artisan openapi:generate --environment=staging
```

**Output:**

```
⚠️  Unknown environment 'staging', using 'artisan' as default
```

**Location:** `src/Commands/GenerateOpenApiSpec.php:96-101`

**HTTP Controller:**

```bash theme={null}
curl "http://localhost:8000/documentation/environment/staging/postman"
```

**HTTP Response (404):**

```json theme={null}
{
  "error": "Failed to generate environment",
  "message": "Environment 'staging' not found in config/openapi.php"
}
```

**Location:** `src/Controllers/OpenApiController.php:216-221`

***

### Available Environments

Define environments in your configuration:

```php theme={null}
// config/openapi.php
'environments' => [
    'base' => [
        'name' => 'Base Environment',
        'variables' => [...],
    ],
    'artisan' => [
        'name' => 'Artisan Server',
        'base_url' => 'http://127.0.0.1:8000',
        'parent' => 'base',
    ],
    'local' => [
        'name' => 'Local Server',
        'base_url' => 'http://localhost/myapp',
        'parent' => 'base',
    ],
    'production' => [
        'name' => 'Production Server',
        'base_url' => 'https://api.example.com',
        'parent' => 'base',
    ],
],
```

**Valid environments:** `base`, `artisan`, `local`, `production`\
**Invalid environments:** `staging`, `development`, `qa` (unless you add them)

***

## Generic Exceptions

Thrown for unexpected errors during generation.

**Exception Class:** `\Exception`

### Common Scenarios

1. **Invalid JSON templates**
2. **Missing configuration keys**
3. **File system errors**
4. **Reflection errors** (when inspecting controllers/models)

***

### Source Locations

**Artisan Command:**

**Location:** `src/Commands/GenerateOpenApiSpec.php:161-170`

```php theme={null}
catch (\Exception $e) {
    $this->error('❌ Failed to generate specification');
    $this->error($e->getMessage());

    if ($this->output->isVerbose()) {
        $this->error($e->getTraceAsString());
    }

    return self::FAILURE;
}
```

**HTTP Controller:**

**Location:** `src/Controllers/OpenApiController.php:91-96`

```php theme={null}
catch (\Exception $e) {
    return response()->json([
        'error' => 'Failed to generate specification',
        'message' => $e->getMessage(),
    ], 500);
}
```

***

### Example Scenarios

**Missing Configuration:**

```php theme={null}
// If config/openapi.php is not published
try {
    $spec = OpenApiGenerator::generate();
} catch (\Exception $e) {
    // Could throw if critical config is missing
}
```

**File System Errors:**

```bash theme={null}
# If output directory is not writable
php artisan openapi:generate --output=/root/spec.json
# Exception: Unable to write file to /root/spec.json
```

**Reflection Errors:**

If a controller class cannot be inspected (rare):

```php theme={null}
// Controller with syntax errors or missing dependencies
// May throw ReflectionException during route processing
```

***

## Error Handling Best Practices

### Programmatic Usage

```php theme={null}
use Ronu\OpenApiGenerator\Facades\OpenApiGenerator;
use Illuminate\Support\Facades\Log;

try {
    $spec = OpenApiGenerator::generate(
        apiTypes: request()->input('api_types'),
        environment: request()->input('environment')
    );

    return response()->json($spec);

} catch (\InvalidArgumentException $e) {
    // User input error - 422 Unprocessable Entity
    Log::warning('Invalid OpenAPI generation request', [
        'error' => $e->getMessage(),
        'input' => request()->all(),
    ]);

    return response()->json([
        'error' => 'Invalid request parameters',
        'message' => $e->getMessage(),
    ], 422);

} catch (\Exception $e) {
    // Server error - 500 Internal Server Error
    Log::error('OpenAPI generation failed', [
        'error' => $e->getMessage(),
        'trace' => $e->getTraceAsString(),
    ]);

    return response()->json([
        'error' => 'Generation failed',
        'message' => config('app.debug') ? $e->getMessage() : 'An error occurred',
    ], 500);
}
```

***

### Artisan Command Handling

The command already handles exceptions gracefully:

```bash theme={null}
php artisan openapi:generate --api-type=invalid
```

**Output:**

```
❌ Failed to generate specification
Unknown or disabled API types: invalid. Available types: api, mobile, admin
```

**With Verbose Flag:**

```bash theme={null}
php artisan openapi:generate --api-type=invalid -v
```

**Output includes stack trace for debugging.**

***

### Validation Before Generation

**Validate API Types:**

```php theme={null}
use Ronu\OpenApiGenerator\Services\OpenApiServices;

function validateApiTypes(array $types): bool
{
    $service = app(OpenApiServices::class);
    $available = array_keys(config('openapi.api_types'));

    return empty(array_diff($types, $available));
}

if (!validateApiTypes(['api', 'mobile'])) {
    // Handle invalid types before attempting generation
}
```

**Validate Environments:**

```php theme={null}
use Ronu\OpenApiGenerator\Services\EnvironmentGenerator;

function validateEnvironment(string $env): bool
{
    $generator = app(EnvironmentGenerator::class);
    return $generator->isValidEnvironment($env);
}

if (!validateEnvironment('staging')) {
    // Fallback to default or show error
}
```

***

## Testing Exception Handling

### Feature Test Example

```php theme={null}
// tests/Feature/OpenApiExceptionTest.php
namespace Tests\Feature;

use Tests\TestCase;
use Ronu\OpenApiGenerator\Facades\OpenApiGenerator;

class OpenApiExceptionTest extends TestCase
{
    /** @test */
    public function throws_exception_for_invalid_api_type()
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->expectExceptionMessage('Unknown or disabled API types: invalid');

        OpenApiGenerator::generate(apiTypes: ['invalid']);
    }

    /** @test */
    public function throws_exception_for_invalid_environment()
    {
        $this->expectException(\InvalidArgumentException::class);
        $this->expectExceptionMessage("Environment 'staging' not found");

        OpenApiGenerator::generate(environment: 'staging');
    }

    /** @test */
    public function http_endpoint_returns_422_for_invalid_api_type()
    {
        $response = $this->get('/documentation/openapi.json?api_type=invalid');

        $response->assertStatus(422);
        $response->assertJson([
            'error' => 'Invalid api_type parameter',
        ]);
    }

    /** @test */
    public function command_fails_gracefully_for_invalid_input()
    {
        $this->artisan('openapi:generate', ['--api-type' => 'invalid'])
            ->expectsOutput('❌ Failed to generate specification')
            ->assertExitCode(1);
    }
}
```

***

## HTTP Status Codes

When using HTTP routes, exceptions map to appropriate status codes:

| Exception Type             | HTTP Status | Description                          |
| -------------------------- | ----------- | ------------------------------------ |
| `InvalidArgumentException` | 422         | Unprocessable Entity (invalid input) |
| `Exception` (generic)      | 500         | Internal Server Error                |
| Environment not found      | 404         | Not Found (environment endpoint)     |

**Location:** `src/Controllers/OpenApiController.php`

***

## Debugging Exceptions

### Enable Verbose Logging

```php theme={null}
// config/logging.php
'channels' => [
    'openapi' => [
        'driver' => 'daily',
        'path' => storage_path('logs/openapi.log'),
        'level' => 'debug', // Set to 'debug' for detailed logs
    ],
],
```

### Check Logs

```bash theme={null}
# View recent errors
tail -f storage/logs/openapi.log

# Search for exceptions
grep -i "exception" storage/logs/openapi.log
```

### Use Telescope

If Laravel Telescope is installed, view exceptions in the dashboard:

```
http://localhost:8000/telescope/exceptions
```

***

## Common Solutions

### Problem: Unknown API Type

**Error:**

```
Unknown or disabled API types: admin
```

**Solution:**

Enable the API type in configuration:

```php theme={null}
// config/openapi.php
'api_types' => [
    'admin' => [
        'prefix' => 'admin',
        'enabled' => true, // Change to true
    ],
],
```

***

### Problem: Environment Not Found

**Error:**

```
Environment 'staging' not found in config/openapi.php
```

**Solution:**

Add the environment to configuration:

```php theme={null}
// config/openapi.php
'environments' => [
    // ... existing environments
    'staging' => [
        'name' => 'Staging Server',
        'base_url' => 'https://staging.example.com',
        'parent' => 'base',
    ],
],
```

***

### Problem: File Write Error

**Error:**

```
Unable to write file to /path/to/output.json
```

**Solution:**

Ensure directory exists and is writable:

```bash theme={null}
mkdir -p storage/app/public/openapi
chmod 755 storage/app/public/openapi
```

Or specify a writable output path:

```bash theme={null}
php artisan openapi:generate --output=./public/openapi.json
```

***

## Related Documentation

<CardGroup cols={2}>
  <Card title="Public API" icon="code" href="/api-reference/public-api">
    Programmatic generation API
  </Card>

  <Card title="Artisan Commands" icon="terminal" href="/api-reference/artisan-commands">
    CLI command reference
  </Card>

  <Card title="Configuration" icon="gear" href="/configuration/reference">
    Configure API types and environments
  </Card>

  <Card title="Testing" icon="flask" href="/guides/testing">
    Test your implementation
  </Card>
</CardGroup>
