jftecnologia/laravel-exceptions
Installation:
composer require jftecnologia/laravel-exceptions
php artisan vendor:publish --provider="Jftecnologia\LaravelExceptions\LaravelExceptionsServiceProvider" --tag="config"
php artisan migrate
config/exceptions.php) and creates the database table for exception logging.First Use Case: Throw a custom exception in a controller or service:
use Jftecnologia\LaravelExceptions\Exceptions\CustomException;
throw new CustomException('User not found', 'Usuário não encontrado');
View Exceptions:
exceptions table. Query via Eloquent:
use Jftecnologia\LaravelExceptions\Models\ExceptionLog;
$logs = ExceptionLog::latest()->take(10)->get();
render() needed).Throwing Exceptions:
Jftecnologia\LaravelExceptions\Exceptions\BaseException for domain-specific errors.
class PaymentFailedException extends BaseException
{
public function __construct(string $message, string $userMessage = null)
{
parent::__construct($message, $userMessage, 402); // HTTP status code
}
}
ExceptionLog::setContext(['key' => 'value']).Logging Channels:
config/exceptions.php:
'channels' => [
'database' => true,
'log' => env('APP_DEBUG', false), // Logs to Laravel's default channel
'slack' => [
'enabled' => env('EXCEPTIONS_SLACK_ENABLED', false),
'webhook' => env('EXCEPTIONS_SLACK_WEBHOOK'),
],
],
Jftecnologia\LaravelExceptions\Contracts\ExceptionChannel.User-Friendly Messages:
throw new CustomException('errors.user.not_found', 'Usuário não encontrado');
config/exceptions.php:
'user_messages' => [
'Jftecnologia\LaravelExceptions\Exceptions\CustomException' => 'Algo deu errado. Tente novamente.',
],
Handling HTTP Exceptions:
HttpException) automatically:
throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException('Route not found');
Middleware Integration:
public function handle($request, Closure $next)
{
ExceptionLog::setContext(['request_id' => $request->header('X-Request-ID')]);
return $next($request);
}
Jftecnologia\LaravelExceptions\Http\JsonExceptionRenderer.user_message field in your error templates (e.g., Blade/React/Vue).exceptions table for analytics (e.g., error rates by endpoint).ExceptionLog in tests:
$this->partialMock(ExceptionLog::class, function ($mock) {
$mock->shouldReceive('store')->once();
});
Context Overwriting:
setContext() overwrites existing context. Use addContext() (if available) or merge manually:
ExceptionLog::setContext(array_merge(
ExceptionLog::getContext(),
['custom_key' => 'value']
));
Database Logging:
$table->softDeletes(); // Add to exceptions table
EXCEPTIONS_LOG_LIMIT in .env to cap log volume.Symfony Exception Quirks:
AccessDeniedHttpException) may not auto-convert. Extend the handler:
use Jftecnologia\LaravelExceptions\Exceptions\BaseException;
throw new BaseException(
'Access denied',
'Você não tem permissão para esta ação.',
403,
null,
new \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException()
);
Localization:
resources/lang/) are published or manually added for multi-language support.en if translations are missing.Debugging:
ExceptionLog::getLastStored() to inspect the last logged exception.EXCEPTIONS_DEBUG in .env to log raw exceptions to the console during development.Custom Channels:
class EmailExceptionChannel implements ExceptionChannel
{
public function send(ExceptionLog $log)
{
Mail::to('admin@example.com')->send(new ExceptionMail($log));
}
}
config/exceptions.php:
'channels' => [
'email' => [
'enabled' => true,
'class' => \App\Channels\EmailExceptionChannel::class,
],
],
Performance:
'channels' => [
'database' => env('APP_ENV') !== 'production',
],
Stack Trace:
'config' => [
'exclude_paths' => [
app_path('Vendor'),
base_path('vendor'),
],
],
Testing:
$this->expectException(CustomException::class);
// Then verify in database or mock the channel.
Artisan Commands:
php artisan exceptions:prune --days=30
php artisan exceptions:list --limit=10
How can I help you explore Laravel packages today?