In the last weeks, I've been working with the team from Honeybadger on a custom resource tool to add Honeybadger error tracking output to Laravel Nova. It's a great addition to Nova and allows the developer to easily get access to error tracking information that, for example, is associated with specific users.

Why Laravel Nova?

Honeybadger already has a great Laravel package available, that takes care of tracking errors that occur in your Laravel application. If you want to take a look at these errors you will then get an email from Honeybadger every time your application has an error to see things like the stack trace of the specific error and maybe even some user or context-related information, you can go to the Honeybadger dashboard and take an in-depth look.

The idea behind a Laravel Nova tool is quite simple - since Laravel Nova is an admin panel, it makes perfect sense to be able to see your errors inside of the dashboard itself.

Errors with context

The cool thing about the Honeybadger Laravel integration is that it automatically adds the context of the currently logged in user to the occurring exceptions. This means that every exception that happens while a user is logged in, is automatically tracked as belonging to a specific user ID.

The Laravel Nova resource tool makes use of this. It allows you to see errors that were created for a particular user.

In order to use the Honeybadger resource tool in your Nova application, all you need to do is add it to the resource that you want to associate with the errors. For example, users:

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),

        // Your other fields

        new \HoneybadgerIo\NovaHoneybadger\Honeybadger,

    ];
}

By default, this is going to look for the resource's id and use it as the user_id and this will give you an output in Nova, similar to this:

screenshot

Of course you can also modify the way that the Honeybadger errors will be looked up, by defining custom "context" strings - a search query language from Honeybadger to lookup previously defined error contexts.

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),

        // Your other fields

        \HoneybadgerIo\NovaHoneybadger\Honeybadger:: fromContextKeyAndAttribute('context.user.email', 'email'),

    ];
}

This would not search for a user ID, but instead lookup all errors that have a context.user.email attribute that is equal to the email column value of the resource that is currently being inspected.

Behind the scenes

Behind the scenes, this is built using a custom Nova resource tool, which is essentially a regular Laravel package that extends Laravel Nova. There were some interesting findings that I made while working on the resource tool.

Since users will load this resource tool into their specific resources, I needed to be able to access the underlying Eloquent model, so that I can perform Honeybadger API requests with the correct context attributes.

In the example above, I would need to access the resource model's email attribute.

Custom Nova resource tools are Vue components, that receive two attributes to identify the eloquent model that is being used:

  • resourceName
  • resourceId

The resourceId is pretty self-explanatory - it's the database ID of the resource that you are currently looking at. But the resourceName is something different. It is more of a slug representation of the resource class that you currently use.

For example, a User resource has a resourceName of users. A Post resource has posts, etc.

But here's the catch: The developer can also change this URI key, by overriding it in their resource class like this:

/**
 * Get the URI key for the resource.
 *
 * @return string
 */
public static function uriKey()
{
    return 'blog-posts';
}

In this case, the Post resource class has a resourceName of blog-posts.

So how can we retrieve the Laravel Eloquent model that is being used for the combination of resourceName and resourceId?

Luckily Laravel Nova got you covered and provides a custom NovaRequest class - this class behaves like a regular Laravel Request class, but has some additional helper methods. One of which is findModelOrFail.

Defining the route

In order to use the findModelOrFail method, you first need to define a route that accepts the resource name and the ID. This route is defined inside of our custom Nova resource tool.

Route::get('/{resource}/{resourceId}', 'ToolController@fetch');

The naming of these parameters is important, as these names are being used inside of the NovaRequest class.

Next, it's time to implement the ToolController fetch method:

use Laravel\Nova\Http\Requests\NovaRequest;

class ToolController
{
     public function fetch(NovaRequest $request)
    {
        $model = $request->findModelOrFail($request->resourceId);
    }
}

Just make sure to import the NovaRequest class and typehint it in your controller method, to make use of it.

Then you can call one of the various helper methods to access models or resources that belong to the incoming resource name and ID.

I had a lot of fun building this resource tool and learned a lot of new, interesting things about how Laravel Nova works internally.

If you want to use a great error tracking library in combination with Laravel and Nova, you should take a look at Honeybadger.