# RulePreventsExecutionException

## Overview

`RulePreventsExecutionException` is a custom exception class in the Midnite81\Guardian package. This exception is thrown when a rate limiting rule prevents the execution of a request in the Guardian system.

## Class Details

* **Namespace**: `Midnite81\Guardian\Exceptions`
* **Extends**: `Exception`

## Purpose

The primary purpose of this exception is to provide detailed information when a request is blocked due to rate limiting rules. It encapsulates the specific rule that caused the prevention, allowing for more informative error handling and logging.

## Properties

* `protected ?RateLimitRule $preventingRule`: Stores the rule that prevented the execution. It can be null if no specific rule is identified.

## Constructor

```php
public function __construct(?RateLimitRule $preventingRule = null)
```

The constructor takes an optional `RateLimitRule` object, which represents the rule that prevented the execution.

## Methods

### getPreventingRule

```php
public function getPreventingRule(): ?RateLimitRule
```

Returns the `RateLimitRule` object that prevented the execution, or `null` if no specific rule was identified.

### getErrorMessageFromRule (protected)

```php
protected function getErrorMessageFromRule(): string
```

Generates a human-readable error message based on the preventing rule. This method is used internally to create the exception message.

## Usage

This exception is typically thrown by the Guardian system when a rate limit is exceeded. You can catch this exception to handle rate limiting scenarios in your application.

Example:

```php
use Midnite81\Guardian\Exceptions\RulePreventsExecutionException;

try {
    // Your Guardian-protected code here
} catch (RulePreventsExecutionException $e) {
    $rule = $e->getPreventingRule();
    if ($rule) {
        echo "Request blocked. Rate limit: {$rule->getLimit()} requests per {$rule->getDuration()} {$rule->getInterval()->value}.";
    } else {
        echo "Request blocked by an unspecified rule.";
    }
}
```

## Error Messages

The exception provides detailed error messages:

* If a specific rule prevented execution:

  ```
  Cannot execute the request. Rate limit exceeded: X requests per Y [interval].
  ```

  Where X is the limit, Y is the duration, and \[interval] is the time unit (e.g., second, minute, hour).
* If no specific rule is identified:

  ```
  Cannot execute the request because a rule prevents it.
  ```

## Integration with Guardian

This exception is thrown by the `Guardian::send()` method when `$throwIfRulePrevents` is set to `true` (which is the default behavior). It allows developers to handle rate limiting scenarios gracefully in their applications.

## Best Practices

1. Always catch this exception when working with Guardian-protected code sections.
2. Use the information provided by the exception to inform users about the rate limit and when they can retry.
3. Consider implementing a backoff strategy or queue system for requests that hit rate limits frequently.

By utilizing `RulePreventsExecutionException`, you can create more robust and user-friendly applications that gracefully handle rate limiting scenarios.
