Error Handling
Handle errors like a pro! ๐ก๏ธ The Vizra ADK provides a robust error handling system with specialized exceptions to help you build resilient AI agents that gracefully handle the unexpected.
๐ Exception Types
The framework includes three specialized exception classes that extend PHP's base \Exception
class:
๐ AgentNotFoundException
Thrown when attempting to access or execute an agent that doesn't exist in the registry.
use Vizra\VizraADK\Exceptions\AgentNotFoundException;
// Example from AgentRegistry::getAgent()
if (!isset($this->registeredAgents[$name])) {
throw new AgentNotFoundException("Agent '{$name}' is not registered.");
}
โ๏ธ AgentConfigurationException
Thrown when there are issues with agent configuration, such as invalid settings or missing required parameters.
use Vizra\VizraADK\Exceptions\AgentConfigurationException;
// Example usage
if (!class_exists($config)) {
throw new AgentConfigurationException(
"Agent class '{$config}' does not exist."
);
}
๐ง ToolExecutionException
Thrown when errors occur during tool execution, including invalid parameters or runtime failures.
use Vizra\VizraADK\Exceptions\ToolExecutionException;
// Example in tool execution
try {
$result = $tool->execute($arguments, $context);
} catch (\Exception $e) {
throw new ToolExecutionException(
"Tool '{$toolName}' failed: " . $e->getMessage()
);
}
๐ฎ Handling Exceptions in Controllers
The AgentApiController
demonstrates comprehensive exception handling:
use Vizra\VizraADK\Facades\Agent;
use Vizra\VizraADK\Exceptions\AgentNotFoundException;
use Vizra\VizraADK\Exceptions\ToolExecutionException;
use Vizra\VizraADK\Exceptions\AgentConfigurationException;
class AgentApiController extends Controller
{
public function handleAgentInteraction(Request $request): JsonResponse
{
try {
// Check if agent exists
if (!Agent::hasAgent($agentName)) {
return response()->json([
'error' => "Agent '{$agentName}' is not registered or found.",
'message' => "Please ensure the agent is registered..."
], 404);
}
// Execute agent
$response = Agent::run($agentName, $input, $sessionId);
return response()->json([
'agent_name' => $agentName,
'session_id' => $sessionId,
'response' => $response,
]);
} catch (AgentNotFoundException $e) {
logger()->error("Agent not found: " . $e->getMessage());
return response()->json([
'error' => "Agent '{$agentName}' could not be found or loaded.",
'detail' => $e->getMessage()
], 404);
} catch (ToolExecutionException $e) {
logger()->error("Tool execution error for agent {$agentName}: " . $e->getMessage(), [
'exception' => $e
]);
return response()->json([
'error' => 'A tool required by the agent failed to execute.',
'detail' => $e->getMessage()
], 500);
} catch (AgentConfigurationException $e) {
logger()->error("Agent configuration error for agent {$agentName}: " . $e->getMessage(), [
'exception' => $e
]);
return response()->json([
'error' => 'Agent configuration error.',
'detail' => $e->getMessage()
], 500);
} catch (\Throwable $e) {
// Catch-all for unexpected errors
logger()->error("Error during agent '{$agentName}' execution: " . $e->getMessage(), [
'exception' => $e
]);
return response()->json([
'error' => 'An unexpected error occurred while processing your request.',
'detail' => $e->getMessage()
], 500);
}
}
}
๐ป Error Handling in Commands
Artisan commands handle errors gracefully to provide helpful feedback:
// Example from RunEvalCommand
try {
$evaluation = $this->loadEvaluation($evaluationName);
$results = $evaluation->run();
} catch (\Exception $e) {
$this->error("โ Evaluation failed: " . $e->getMessage());
return 1; // Return non-zero exit code
}
๐ญ Error Handling in Services
Services like AgentRegistry
validate configuration and throw appropriate exceptions:
public function getAgent(string $name): BaseAgent
{
if (!isset($this->registeredAgents[$name])) {
throw new AgentNotFoundException("Agent '{$name}' is not registered.");
}
$config = $this->registeredAgents[$name];
if (is_string($config)) {
if (!class_exists($config)) {
throw new AgentConfigurationException(
"Agent class '{$config}' does not exist."
);
}
$agent = new $config();
if (!$agent instanceof BaseAgent) {
throw new AgentConfigurationException(
"Agent class '{$config}' must extend BaseAgent."
);
}
return $agent;
}
// Handle array configuration...
}
โจ Best Practices
1๏ธโฃ Use Specific Exception Types
Always throw the most specific exception type for the error scenario:
// โ
Good - specific exception
if (!$agent) {
throw new AgentNotFoundException("Agent 'chatbot' not found");
}
// โ Avoid - generic exception
if (!$agent) {
throw new \Exception("Agent not found");
}
2๏ธโฃ Provide Meaningful Error Messages
Include context in error messages to help with debugging:
throw new ToolExecutionException(
"Weather tool failed for location '{$location}': API key not configured"
);
3๏ธโฃ Log Errors with Context
Always log errors with relevant context for debugging:
catch (ToolExecutionException $e) {
logger()->error("Tool execution failed", [
'agent' => $agentName,
'tool' => $e->getToolName(),
'session_id' => $sessionId,
'exception' => $e
]);
}
4๏ธโฃ Handle Errors at the Right Level
Let exceptions bubble up to where they can be handled appropriately:
// In a tool - let exception bubble up
public function execute(array $arguments, AgentContext $context): string
{
if (!isset($arguments['location'])) {
throw new ToolExecutionException("Location parameter is required");
}
// Tool logic...
}
// In the controller - handle and return appropriate response
try {
$result = $agent->run($input);
} catch (ToolExecutionException $e) {
return response()->json(['error' => $e->getMessage()], 400);
}
๐จ Creating Custom Exceptions
You can create custom exceptions for your specific use cases:
<?php
namespace App\Exceptions;
use Vizra\VizraADK\Exceptions\ToolExecutionException;
class ApiRateLimitException extends ToolExecutionException
{
protected string $service;
protected int $retryAfter;
public function __construct(string $service, int $retryAfter)
{
$this->service = $service;
$this->retryAfter = $retryAfter;
parent::__construct(
"Rate limit exceeded for {$service}. Retry after {$retryAfter} seconds."
);
}
public function getRetryAfter(): int
{
return $this->retryAfter;
}
}
๐ Error Recovery Strategies
๐ Graceful Degradation
Provide fallback behavior when non-critical operations fail:
public function execute(array $arguments, AgentContext $context): string
{
try {
// Try to get weather from primary API
$weather = $this->primaryApi->getWeather($location);
} catch (ToolExecutionException $e) {
logger()->warning("Primary weather API failed, using fallback", [
'error' => $e->getMessage()
]);
// Fallback to secondary API
try {
$weather = $this->fallbackApi->getWeather($location);
} catch (ToolExecutionException $e) {
// Return cached or default response
return json_encode([
'error' => 'Weather service temporarily unavailable',
'cached' => true,
'data' => $this->getCachedWeather($location)
]);
}
}
return json_encode($weather);
}
๐ Retry Logic
Implement retry logic for transient failures:
use Illuminate\Support\Facades\Http;
public function executeWithRetry(callable $operation, int $maxAttempts = 3)
{
$attempt = 1;
while ($attempt <= $maxAttempts) {
try {
return $operation();
} catch (ToolExecutionException $e) {
if ($attempt === $maxAttempts) {
throw $e;
}
logger()->warning("Operation failed, retrying", [
'attempt' => $attempt,
'max_attempts' => $maxAttempts,
'error' => $e->getMessage()
]);
sleep(pow(2, $attempt)); // Exponential backoff
$attempt++;
}
}
}
๐งช Testing Error Handling
Always test your error handling paths:
use Vizra\VizraADK\Exceptions\AgentNotFoundException;
test('throws exception for non-existent agent', function () {
$registry = app(AgentRegistry::class);
expect(fn() => $registry->getAgent('non-existent'))
->toThrow(AgentNotFoundException::class, "Agent 'non-existent' is not registered.");
});
test('handles tool execution failure gracefully', function () {
$response = $this->postJson('/api/vizra/interact', [
'agent_name' => 'test_agent',
'input' => 'trigger tool failure'
]);
$response->assertStatus(500)
->assertJson([
'error' => 'A tool required by the agent failed to execute.'
]);
});
๐ Ready to Build Resilient Agents?
Master error handling and continue your journey:
Ready for Professional AI Agent Evaluation? ๐
Evaluate and debug your Vizra ADK agents with professional cloud tools. Get early access to Vizra Cloud and be among the first to experience advanced evaluation and trace analysis at scale.
Join other developers already on the waitlist. No spam, just launch updates.