Handling Large Uploads and Improving Error Notifications in a Filament Application
When working with the Reimpact/platform project, we encountered an issue with large upload deletions that resulted in failures and an unhelpful JSON response. This post describes how we resolved the deletion failure and improved the user experience by displaying a Filament notification instead of a raw JSON page.
The Problem
Deleting a large number of generated reports and calculated data before removing related warehouse data was causing a restrictOnDelete foreign key violation. Additionally, when errors occurred during Livewire requests, the system was returning a JSON response, which isn't ideal for a Filament-based admin panel.
The Solution
First, we addressed the foreign key constraint violation by adjusting the deletion order. We made sure to delete the warehouses before attempting to delete associated reports and calculated data. This prevents the database from rejecting the deletion due to the restrictOnDelete constraint.
Second, to improve the user experience, we modified the application's error handling to ensure that Filament notifications are displayed instead of raw JSON responses for Livewire requests. This provides a more intuitive and user-friendly way to communicate errors within the Filament admin panel.
Code Example: Custom Exception Handling
While the specific code changes aren't available, the concept can be illustrated with an example of a custom exception handler in Laravel. This handler checks if the request is a Livewire request and, if so, returns a Filament notification instead of a JSON response:
use Livewire\Livewire;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Filament\Facades\Filament;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
/**
* @param $request
* @param \Throwable $e
* @return mixed
*/
public function render($request, \Throwable $e)
{
if ($request->expectsJson()) {
if ($e instanceof HttpExceptionInterface) {
$statusCode = $e->getStatusCode();
} else {
$statusCode = 500;
}
if (Livewire::isLivewireRequest()) {
Filament::notify('danger', 'An error occurred: ' . $e->getMessage());
return redirect()->back();
}
return response()->json(['message' => $e->getMessage()], $statusCode);
}
return parent::render($request, $e);
}
In this example, the render function checks if the request expects JSON and if it's a Livewire request. If both conditions are true, it displays a Filament notification with the error message and redirects the user back. Otherwise, it returns a standard JSON response or defers to the parent handler.
Key Takeaways
- Database Constraints: Always be mindful of foreign key constraints when deleting related data. Ensure that you delete data in the correct order to avoid violations.
- User Experience: Provide user-friendly error notifications, especially in admin panels. Avoid raw JSON responses that are difficult for users to understand.
- Custom Error Handling: Implement custom exception handlers to tailor error responses based on the request type and application context. This allows you to provide the best possible experience for your users.