Repository: echolabsdev/prism (php)

Issue:
Exception improvement
I think the below error could be caught and improved to make it a little more clear as to what the issue is.

![SCR-20241022-jhht](https://github.com/user-attachments/assets/8c61b252-d734-4ae4-a1a2-cf64984367d0)

It results from you defining a Tool with expected parameters and then not including those args in your callable (in my case an `__invoke` method).

Caught me out a few times now when adjusting the Tool parameters and not accounting for them in the handling. The exception makes sense, I think it could be caught and transformed into something more helpful.

Pull request description:
Handle exception when invalid param passed to a tool
Resolves #39 

Patch:
diff --git a/src/Exceptions/PrismException.php b/src/Exceptions/PrismException.php
index 30e2954..c1f3ae8 100644
--- a/src/Exceptions/PrismException.php
+++ b/src/Exceptions/PrismException.php
@@ -39,6 +39,14 @@ class PrismException extends Exception
         );
     }
 
+    public static function invalidParameterInTool(string $toolName, Throwable $previous): self
+    {
+        return new self(
+            sprintf('Invalid parameters for tool : %s', $toolName),
+            previous: $previous
+        );
+    }
+
     public static function providerResponseError(string $message): self
     {
         return new self($message);
diff --git a/src/Tool.php b/src/Tool.php
index 976a867..02316ac 100644
--- a/src/Tool.php
+++ b/src/Tool.php
@@ -4,20 +4,25 @@ declare(strict_types=1);
 
 namespace EchoLabs\Prism;
 
+use ArgumentCountError;
 use Closure;
 use EchoLabs\Prism\Contracts\Schema;
+use EchoLabs\Prism\Exceptions\PrismException;
 use EchoLabs\Prism\Schema\ArraySchema;
 use EchoLabs\Prism\Schema\BooleanSchema;
 use EchoLabs\Prism\Schema\EnumSchema;
 use EchoLabs\Prism\Schema\NumberSchema;
 use EchoLabs\Prism\Schema\ObjectSchema;
 use EchoLabs\Prism\Schema\StringSchema;
+use InvalidArgumentException;
+use Throwable;
+use TypeError;
 
 class Tool
 {
     protected string $name = '';
 
-    protected string $description = '';
+    protected string $description;
 
     /** @var array<string, array<string, mixed>> */
     protected array $parameters = [];
@@ -155,9 +160,17 @@ class Tool
         return $this->description;
     }
 
-    /** @param string|int|float $args */
-    public function handle(...$args): ?string
+    /**
+     * @param  string|int|float  $args
+     *
+     * @throws PrismException|Throwable
+     */
+    public function handle(...$args): string
     {
-        return call_user_func($this->fn, ...$args);
+        try {
+            return call_user_func($this->fn, ...$args);
+        } catch (ArgumentCountError|InvalidArgumentException|TypeError $e) {
+            throw PrismException::invalidParameterInTool($this->name, $e);
+        }
     }
 }


Test patch:
diff --git a/tests/ToolTest.php b/tests/ToolTest.php
index 26ef865..06f692a 100644
--- a/tests/ToolTest.php
+++ b/tests/ToolTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Tests;
 
+use EchoLabs\Prism\Exceptions\PrismException;
 use EchoLabs\Prism\Facades\Tool as ToolFacade;
 use EchoLabs\Prism\Schema\BooleanSchema;
 use EchoLabs\Prism\Schema\StringSchema;
@@ -126,3 +127,20 @@ it('can have fluent parameters', function (): void {
 
     expect($tool->requiredParameters())->not->toContain('query');
 });
+
+it('can throw a prism custom exception for invalid parameters', function (): void {
+    $searchTool = (new Tool)
+        ->as('search')
+        ->for('useful for searching current data')
+        ->withParameter(new StringSchema('query', 'the search query'))
+        ->using(function (string $query): string {
+            expect($query)->toBe('What time is the event?');
+
+            return 'The event is at 3pm eastern';
+        });
+
+    $this->expectException(PrismException::class);
+    $this->expectExceptionMessage('Invalid parameters for tool : search');
+
+    $searchTool->handle([]);
+});