Skip to content

Commit f9acb52

Browse files
authored
Merge pull request WordPress#78 from Ref34t/feature/exception-hierarchy
Implement Exception Hierarchy For Better Error Handling
2 parents 2fd7994 + ef9a3bb commit f9acb52

File tree

52 files changed

+774
-175
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+774
-175
lines changed

AGENTS.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ The production code in `src` follows a structured namespace hierarchy under the
8383

8484
All parameters, return values, and properties must use explicit type hints, except in cases where providing the correct type hint would be impossible given limitations of backward compatibility with PHP 7.4. In any case, concrete type annotations using PHPStan should be present.
8585

86+
### Exception handling
87+
88+
All exceptions must use the project's custom exception classes rather than PHP built-in exceptions. This includes:
89+
90+
- Use the custom primitive exceptions in `WordPress\AiClient\Common\Exception\` instead of the PHP primitive exceptions
91+
- If a PHP primitive exception is needed that doesn't have a custom exception counterpart, then create one that extends the primitive and implements AiClientExceptionInterface
92+
- All custom exceptions implement `WordPress\AiClient\Exceptions\AiClientExceptionInterface` for unified exception handling
93+
- Follow usage-driven design: only implement static factory methods that are actually used in the codebase
94+
8695
### Naming conventions
8796

8897
The following naming conventions must be followed for consistency and autoloading:

src/AiClient.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
namespace WordPress\AiClient;
66

77
use WordPress\AiClient\Builders\PromptBuilder;
8+
use WordPress\AiClient\Common\Exception\InvalidArgumentException;
9+
use WordPress\AiClient\Common\Exception\RuntimeException;
810
use WordPress\AiClient\ProviderImplementations\Anthropic\AnthropicProvider;
911
use WordPress\AiClient\ProviderImplementations\Google\GoogleProvider;
1012
use WordPress\AiClient\ProviderImplementations\OpenAi\OpenAiProvider;
@@ -312,7 +314,7 @@ public static function generateSpeechResult(
312314
*/
313315
public static function message(?string $text = null)
314316
{
315-
throw new \RuntimeException(
317+
throw new RuntimeException(
316318
'MessageBuilder is not yet available. This method depends on builder infrastructure. ' .
317319
'Use direct generation methods (generateTextResult, generateImageResult, etc.) for now.'
318320
);
@@ -332,7 +334,7 @@ private static function validateModelOrConfigParameter($modelOrConfig): void
332334
&& !$modelOrConfig instanceof ModelInterface
333335
&& !$modelOrConfig instanceof ModelConfig
334336
) {
335-
throw new \InvalidArgumentException(
337+
throw new InvalidArgumentException(
336338
'Parameter must be a ModelInterface instance (specific model), ' .
337339
'ModelConfig instance (for auto-discovery), or null (default auto-discovery). ' .
338340
sprintf('Received: %s', is_object($modelOrConfig) ? get_class($modelOrConfig) : gettype($modelOrConfig))

src/Builders/PromptBuilder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
namespace WordPress\AiClient\Builders;
66

7-
use InvalidArgumentException;
8-
use RuntimeException;
7+
use WordPress\AiClient\Common\Exception\InvalidArgumentException;
8+
use WordPress\AiClient\Common\Exception\RuntimeException;
99
use WordPress\AiClient\Files\DTO\File;
1010
use WordPress\AiClient\Files\Enums\FileTypeEnum;
1111
use WordPress\AiClient\Messages\DTO\Message;

src/Common/AbstractDataTransferObject.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
namespace WordPress\AiClient\Common;
66

7-
use InvalidArgumentException;
87
use JsonSerializable;
98
use stdClass;
109
use WordPress\AiClient\Common\Contracts\WithArrayTransformationInterface;
1110
use WordPress\AiClient\Common\Contracts\WithJsonSchemaInterface;
11+
use WordPress\AiClient\Common\Exception\InvalidArgumentException;
1212

1313
/**
1414
* Abstract base class for all Data Value Objects in the AI Client.

src/Common/AbstractEnum.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
namespace WordPress\AiClient\Common;
66

77
use BadMethodCallException;
8-
use InvalidArgumentException;
98
use JsonSerializable;
109
use ReflectionClass;
11-
use RuntimeException;
10+
use WordPress\AiClient\Common\Exception\InvalidArgumentException;
11+
use WordPress\AiClient\Common\Exception\RuntimeException;
1212

1313
/**
1414
* Abstract base class for enum-like behavior in PHP 7.4.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WordPress\AiClient\Common\Contracts;
6+
7+
use Throwable;
8+
9+
/**
10+
* Base interface for all AI Client exceptions.
11+
*
12+
* This interface allows callers to catch all AI Client specific exceptions
13+
* with a single catch statement.
14+
*
15+
* @since n.e.x.t
16+
*/
17+
interface AiClientExceptionInterface extends Throwable
18+
{
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WordPress\AiClient\Common\Exception;
6+
7+
use WordPress\AiClient\Common\Contracts\AiClientExceptionInterface;
8+
9+
/**
10+
* Exception thrown when an invalid argument is provided.
11+
*
12+
* This extends PHP's built-in InvalidArgumentException while implementing
13+
* the AI Client exception interface for consistent catch handling.
14+
*
15+
* @since n.e.x.t
16+
*/
17+
class InvalidArgumentException extends \InvalidArgumentException implements AiClientExceptionInterface
18+
{
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace WordPress\AiClient\Common\Exception;
6+
7+
use WordPress\AiClient\Common\Contracts\AiClientExceptionInterface;
8+
9+
/**
10+
* Exception thrown for runtime errors.
11+
*
12+
* This extends PHP's built-in RuntimeException while implementing
13+
* the AI Client exception interface for consistent catch handling.
14+
*
15+
* @since n.e.x.t
16+
*/
17+
class RuntimeException extends \RuntimeException implements AiClientExceptionInterface
18+
{
19+
}

src/Files/DTO/File.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55
namespace WordPress\AiClient\Files\DTO;
66

7-
use InvalidArgumentException;
8-
use RuntimeException;
97
use WordPress\AiClient\Common\AbstractDataTransferObject;
8+
use WordPress\AiClient\Common\Exception\InvalidArgumentException;
9+
use WordPress\AiClient\Common\Exception\RuntimeException;
1010
use WordPress\AiClient\Files\Enums\FileTypeEnum;
1111
use WordPress\AiClient\Files\ValueObjects\MimeType;
1212

src/Files/ValueObjects/MimeType.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace WordPress\AiClient\Files\ValueObjects;
66

7-
use InvalidArgumentException;
7+
use WordPress\AiClient\Common\Exception\InvalidArgumentException;
88

99
/**
1010
* Value object representing a MIME type.

0 commit comments

Comments
 (0)