PHPackages                             elle-the-dev/glove - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Debugging &amp; Profiling](/categories/debugging)
4. /
5. elle-the-dev/glove

ActiveLibrary[Debugging &amp; Profiling](/categories/debugging)

elle-the-dev/glove
==================

Exception handling for Laravel that catches like a glove.

v0.2.0(3y ago)021[4 PRs](https://github.com/elle-the-dev/glove/pulls)MITPHPPHP 7.\*|8.\*

Since Dec 4Pushed 1y ago1 watchersCompare

[ Source](https://github.com/elle-the-dev/glove)[ Packagist](https://packagist.org/packages/elle-the-dev/glove)[ RSS](/packages/elle-the-dev-glove/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (10)Versions (18)Used By (0)

Laravel Glove
-------------

[](#laravel-glove)

Catch exceptions with Laravel Glove. The main goal of this package is to make it as easy as possible to add custom error pages and create custom error handlers to do whatever we need.

This means

- [Custom error pages](#error-pages) that don't need a handler - just point to the view in the config
- [Status codes](#http-status-codes) and [log levels](#logging) specified in the config
- [Simple interface](#custom-exception-handling) to implement that lets us return a response and be done
- [Cascading handlers](#custom-handler-without-a-response) simply by omitting a response

### Requirements

[](#requirements)

Laravel Glove is written for Laravel 5.5 and higher, thus also requiring PHP 7.0 and higher.

### Installation

[](#installation)

Installation is done via composer

```
composer require ellehamilton/glove
```

Once installed we need to run

```
php artisan vendor:publish
```

If we don't use auto-discovery, we'll need to add `GloveServiceProvider` to the providers array in `config/app.php`

```
ElleTheDev\Glove\Providers\GloveServiceProvider::class,
```

Glove integrates automatically with [Whoops](https://github.com/filp/whoops) with no additional configuration.

### Error Pages

[](#error-pages)

We can easily customize our error pages by updating `config/glove-codes.php`

#### Basic Example

[](#basic-example)

Let's send all 404 status codes to our `errors.404` view.

```
...

404 => [
    'view' => [
        'http' => 'errors.404',
        'ajax' => 'vendor.glove.ajax.exception'
    ]
]

...
```

#### Error Pages with Data

[](#error-pages-with-data)

Additional data can be passed to our view to assist with reusing views for multiple status codes.

```
...

404 => [
    'view' => [
        'http' => 'errors.404',
        'ajax' => 'vendor.glove.ajax.exception'
    ],
    'data' => [
        'foo' => 'bar'
    ]
]

...
```

If we want our view to show up as a page regardless of debug settings, we can set the debug override to false so that, for example, 404 pages always appear as such instead of showing a Whoops debug page.

```
...

404 => [
    'view' => [
        'http' => 'errors.404',
        'ajax' => 'vendor.glove.ajax.exception'
    ],
    'debug' => false
]

...
```

`debug` defaults to `true` when absent.

By changing the `ajax` view, we can use our own custom AJAX format. By default, the provided view will result in the format of

```
{ error: { code: 404, message: "404 Page Not Found. The address you were looking for does not exist." } }
```

### HTTP Status Codes

[](#http-status-codes)

We can specify which status to code for which exceptions in `config/glove.php`

Let's make `MyException` emit a `403` status

```
'statusCodes' => [
    ...

    \App\Exceptions\MyException::class => 403,

    ...
]
```

Status codes are interpreted in order from top to bottom. The first exception it finds that is an instance of the exception thrown will be the status code used.

e.g if we have the following,

```
'statusCodes' => [
    \App\Exceptions\MyException::class => 403,
    \Exception::class => 500,
];
```

If we throw `\App\Exceptions\MyException` the status code will be `403` because it matches and is first. If we reverse the order,

```
'statusCodes' => [
    \Exception::class => 500,
    \App\Exceptions\MyException::class => 403,
];
```

Then the status code will be `500` because `\App\Exceptions\MyException` is an instance of `Exception` and is matched first.

`\Symfony\Component\HttpKernel\Exception\HttpException` is a special case. When using `abort(403)` or a variant thereof, excluding the case of a `404` status code, will result in a `HttpException` with the status code contained within. Glove handles this case automatically, and interprets an `HttpException` as whatever status code it contains, so it does not need to be included in the status codes configuration unless we wish to override its handling.

### Logging

[](#logging)

Whether or not to log exceptions, and the log level at which to log them, can be specified in `config/glove.php`

Logging is also considered in top-to-bottom order in the same manner as Status Codes.

#### Skipping Logging

[](#skipping-logging)

We can ignore logging on an exception by setting the log level to `ignore`

```
'logLevels' => [
    ...

    \App\Exceptions\MyException::class => 'ignore',

    ...
]
```

#### Changing the Log Level

[](#changing-the-log-level)

We can change the log level from the default 'error' to any of the Laravel log levels.

```
'logLevels' => [
    \App\Exceptions\MyException::class => 'critical'
]
```

### Custom Exception Handling

[](#custom-exception-handling)

Writing a custom exception handler is as simple as implementing the `\ElleTheDev\Glove\Contracts\Handler` then telling it when to run in `config/glove.php`

There's only one function to implement.

```
public function handle(\Illuminate\Http\Request $request, \Exception $e);
```

#### Custom Response

[](#custom-response)

To send back a customized response, return a response from the `handle` method.

Let's say we have a custom exception, `MyException`

```
namespace App\Exceptions;

class MyException extends \Exception
{
}
```

We'll write a custom handler to handle that exception.

```
namespace App\Exceptions\Handlers;

use ElleTheDev\Glove\Contracts\Handler;
use Illuminate\Http\Request;
use Exception;

class MyHandler implements Handler
{
    public function handle(Request $request, Exception $e)
    {
        return response(json_encode(['foo' => 'bar']))
            ->header('Content-Type', 'application/json');
    }
}
```

Once `MyHandler` exists, we can add it to `config/glove.php`

If we only want it to run if it's an AJAX request, we can add it to the `ajax` section of `handlers`

```
'handlers' => [
    ...

    'ajax' => [
        ...

        \App\Exceptions\MyException::class => [
            \App\Exceptions\Handlers\MyHandler::class
        ],

        ...
    ]

    ...
],
```

An exception can have multiple handlers, as if `null` is returned instead of a `Response` object, it will cascade and continue processing handlers until it does receive a response.

Handlers are interpreted in top-to-bottom order in the same manner as Status Codes.

#### Custom Handler Without a Response

[](#custom-handler-without-a-response)

If we want our handler to do something, but let other handlers deal with how to respond, we can simply omit a return value or return null in order to cascade.

```
namespace App\Exceptions\Handlers;

use ElleTheDev\Glove\Contracts\Handler;

class MyHandler implements Handler
{
    public function handle(Request $request, Exception $e)
    {
        \Log::info("Something happened!");
    }
}
```

###  Health Score

29

—

LowBetter than 57% of packages

Maintenance29

Infrequent updates — may be unmaintained

Popularity6

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~184 days

Recently: every ~324 days

Total

12

Last Release

1108d ago

PHP version history (2 changes)v0.1.1PHP ^7.0

v0.2.0PHP 7.\*|8.\*

### Community

Maintainers

![](https://www.gravatar.com/avatar/7dac383dd4c0fb57f4dddc19ea2b70620af00af59b7f166b59c983d2f6beaf26?d=identicon)[ellesaurus](/maintainers/ellesaurus)

---

Top Contributors

[![elle-the-dev](https://avatars.githubusercontent.com/u/272878?v=4)](https://github.com/elle-the-dev "elle-the-dev (19 commits)")

---

Tags

laravelexceptionhandlingexceptions

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/elle-the-dev-glove/health.svg)

```
[![Health](https://phpackages.com/badges/elle-the-dev-glove/health.svg)](https://phpackages.com/packages/elle-the-dev-glove)
```

###  Alternatives

[laravel/framework

The Laravel Framework.

34.8k543.8M20.1k](/packages/laravel-framework)[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M346](/packages/psalm-plugin-laravel)[laravel/horizon

Dashboard and code-driven configuration for Laravel queues.

4.2k95.4M305](/packages/laravel-horizon)[laravel/sail

Docker files for running a basic Laravel application.

1.9k205.7M1.3k](/packages/laravel-sail)[moonshine/moonshine

Laravel administration panel

1.3k253.1k81](/packages/moonshine-moonshine)[spatie/laravel-export

Create a static site bundle from a Laravel app

674146.0k6](/packages/spatie-laravel-export)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
