Skip to content

Commit

Permalink
Fix Twill custom error view and ability to extend handler
Browse files Browse the repository at this point in the history
Twill uses it's own internal exception handler for controllers extending `A17\Twill\Http\Admin\Controller` and `A17\Twill\Http\Front\Controller`, to support unauthenticated requests redirection, custom error views and custom validation error responses.

To be able to render custom exceptions or report them to an external service on route that is mapped to Twill's controller, it is necessary to disable `twill.bind_exception_handler`. Your Laravel handler can then extend Twill's internal handler.

The reasoning behind assigning a custom handler to the FrontController is to be able to redirect unauthenticated requests to `/admin-preview` routes that are registered by the `showWithPreview` route macro. This is the url showing in the CMS permalink when a record is still a draft. Not many Twill users are leveraging this frontend tooling, but it exists, so wanted to provide the rationale behind all this.

This commit is resolving issue for users that were previously extending the handler for the reasons explained above, as well as making sure custom Twill errors view are automatically in use on the admin routes.
  • Loading branch information
ifox committed Sep 2, 2021
1 parent 321da81 commit 312b446
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 63 deletions.
30 changes: 27 additions & 3 deletions src/Exceptions/Handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
namespace A17\Twill\Exceptions;

use Illuminate\Auth\AuthenticationException;
use App\Exceptions\Handler as ExceptionHandler;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

class Handler extends ExceptionHandler
{
Expand All @@ -23,6 +26,23 @@ protected function unauthenticated($request, AuthenticationException $exception)
: redirect()->guest($exception->redirectTo() ?? route('admin.login', Route::current()->parameters()));
}

/**
* Get the view used to render HTTP exceptions.
*
* @param \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface $e
* @return string
*/
protected function getHttpExceptionView(HttpExceptionInterface $e)
{
$usesAdminPath = !empty(config('twill.admin_app_path'));
$adminAppUrl = parse_url(config('twill.admin_app_url'));

$isSubdomainAdmin = !$usesAdminPath && $adminAppUrl['host'] == Request::getHost();
$isSubdirectoryAdmin = $usesAdminPath && Str::starts_with(Request::path(), config('twill.admin_app_path'));

return $this->getTwillErrorView($e->getStatusCode(), !($isSubdomainAdmin || $isSubdirectoryAdmin));
}

/**
* Get the Twill error view used to render a specified HTTP status code.
*
Expand All @@ -32,10 +52,14 @@ protected function unauthenticated($request, AuthenticationException $exception)
protected function getTwillErrorView($statusCode, $frontend = false)
{
if ($frontend) {
return config('twill.frontend.views_path') . ".errors.$statusCode";
$view = config('twill.frontend.views_path') . ".errors.$statusCode";

return view()->exists($view)? $view : "errors::{$statusCode}";
}

return view()->exists("admin.errors.$statusCode") ? "admin.errors.$statusCode" : "twill::errors.$statusCode";
$view = "admin.errors.$statusCode";

return view()->exists($view) ? $view : "twill::errors.$statusCode";
}

protected function invalidJson($request, ValidationException $exception)
Expand Down
19 changes: 0 additions & 19 deletions tests/integration/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,6 @@ public function setUp(): void
$this->copyBlocks();

$this->installTwill();

$this->ensureAppExceptionHandlerExists();
}

/**
Expand Down Expand Up @@ -763,21 +761,4 @@ public function migrate()
public function loadConfig()
{
}

public function ensureAppExceptionHandlerExists()
{
$stubPath = __DIR__.'/../../tests/stubs/classes/AppExceptionHandler.php';

$filePath = __DIR__.'/../../vendor/orchestra/testbench-core/laravel/app/Exceptions/Handler.php';

$dir = dirname($filePath);

if (!file_exists($filePath)) {
if (!file_exists($dir)) {
mkdir($dir, 0755, true);
}

file_put_contents($filePath, file_get_contents($stubPath));
}
}
}
41 changes: 0 additions & 41 deletions tests/stubs/classes/AppExceptionHandler.php

This file was deleted.

0 comments on commit 312b446

Please sign in to comment.