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:
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.