Improve exception handling and model binding
This commit is contained in:
parent
e9ca934cb4
commit
0fca80e7e4
22 changed files with 148 additions and 82 deletions
|
@ -4,6 +4,7 @@ namespace App\Exceptions;
|
|||
|
||||
use Exception;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
|
@ -23,7 +24,8 @@ class Handler extends ExceptionHandler
|
|||
* @var array
|
||||
*/
|
||||
protected $dontReport = [
|
||||
\Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class,
|
||||
NotFoundHttpException::class,
|
||||
ModelNotFoundException::class,
|
||||
];
|
||||
|
||||
/**
|
||||
|
@ -49,35 +51,33 @@ class Handler extends ExceptionHandler
|
|||
{
|
||||
parent::report($throwable);
|
||||
|
||||
if ($throwable instanceof NotFoundHttpException) {
|
||||
return;
|
||||
}
|
||||
if ($this->shouldReport($throwable)) {
|
||||
$guzzle = new Client([
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
]);
|
||||
|
||||
$guzzle = new Client([
|
||||
'headers' => [
|
||||
'Content-Type' => 'application/json',
|
||||
],
|
||||
]);
|
||||
|
||||
$guzzle->post(
|
||||
config('logging.slack'),
|
||||
[
|
||||
'body' => json_encode([
|
||||
'attachments' => [[
|
||||
'fallback' => 'There was an exception.',
|
||||
'pretext' => 'There was an exception.',
|
||||
'color' => '#d00000',
|
||||
'author_name' => app()->environment(),
|
||||
'author_link' => config('app.url'),
|
||||
'fields' => [[
|
||||
'title' => get_class($throwable) ?? 'Unknown Exception',
|
||||
'value' => $throwable->getTraceAsString() ?? '',
|
||||
$guzzle->post(
|
||||
config('logging.slack'),
|
||||
[
|
||||
'body' => json_encode([
|
||||
'attachments' => [[
|
||||
'fallback' => 'There was an exception.',
|
||||
'pretext' => 'There was an exception.',
|
||||
'color' => '#d00000',
|
||||
'author_name' => app()->environment(),
|
||||
'author_link' => config('app.url'),
|
||||
'fields' => [[
|
||||
'title' => get_class($throwable) ?? 'Unknown Exception',
|
||||
'value' => $throwable->getTraceAsString() ?? '',
|
||||
]],
|
||||
'ts' => time(),
|
||||
]],
|
||||
'ts' => time(),
|
||||
]],
|
||||
]),
|
||||
]
|
||||
);
|
||||
]),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Article;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\View\View;
|
||||
use Jonnybarnes\IndieWeb\Numbers;
|
||||
|
@ -14,8 +15,8 @@ class ArticlesController extends Controller
|
|||
/**
|
||||
* Show all articles (with pagination).
|
||||
*
|
||||
* @param int $year
|
||||
* @param int $month
|
||||
* @param int|null $year
|
||||
* @param int|null $month
|
||||
* @return View
|
||||
*/
|
||||
public function index(int $year = null, int $month = null): View
|
||||
|
@ -38,7 +39,12 @@ class ArticlesController extends Controller
|
|||
*/
|
||||
public function show(int $year, int $month, string $slug)
|
||||
{
|
||||
$article = Article::where('titleurl', $slug)->firstOrFail();
|
||||
try {
|
||||
$article = Article::where('titleurl', $slug)->firstOrFail();
|
||||
} catch (ModelNotFoundException $exception) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
if ($article->updated_at->year != $year || $article->updated_at->month != $month) {
|
||||
return redirect('/blog/'
|
||||
. $article->updated_at->year
|
||||
|
@ -59,7 +65,11 @@ class ArticlesController extends Controller
|
|||
public function onlyIdInUrl(int $idFromUrl): RedirectResponse
|
||||
{
|
||||
$realId = resolve(Numbers::class)->b60tonum($idFromUrl);
|
||||
$article = Article::findOrFail($realId);
|
||||
try {
|
||||
$article = Article::findOrFail($realId);
|
||||
} catch (ModelNotFoundException $exception) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
return redirect($article->link);
|
||||
}
|
||||
|
|
|
@ -6,13 +6,14 @@ namespace App\Http\Controllers;
|
|||
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class AuthController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show the login form.
|
||||
*
|
||||
* @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
|
||||
* @return View|RedirectResponse
|
||||
*/
|
||||
public function showLogin()
|
||||
{
|
||||
|
@ -27,7 +28,7 @@ class AuthController extends Controller
|
|||
* Log in a user, set a session variable, check credentials against
|
||||
* the .env file.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function login(): RedirectResponse
|
||||
{
|
||||
|
@ -43,7 +44,7 @@ class AuthController extends Controller
|
|||
/**
|
||||
* Show the form to logout a user.
|
||||
*
|
||||
* @return \Illuminate\View\View|\Illuminate\Http\RedirectResponse
|
||||
* @return View|RedirectResponse
|
||||
*/
|
||||
public function showLogout()
|
||||
{
|
||||
|
@ -58,7 +59,7 @@ class AuthController extends Controller
|
|||
/**
|
||||
* Log the user out from their current session.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse;
|
||||
* @return RedirectResponse;
|
||||
*/
|
||||
public function logout(): RedirectResponse
|
||||
{
|
||||
|
|
|
@ -12,7 +12,7 @@ class BookmarksController extends Controller
|
|||
/**
|
||||
* Show the most recent bookmarks.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
* @return View
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
|
@ -24,8 +24,8 @@ class BookmarksController extends Controller
|
|||
/**
|
||||
* Show a single bookmark.
|
||||
*
|
||||
* @param \App\Models\Bookmark $bookmark
|
||||
* @return \Illuminate\View\View
|
||||
* @param Bookmark $bookmark
|
||||
* @return View
|
||||
*/
|
||||
public function show(Bookmark $bookmark): View
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Contact;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Filesystem\Filesystem;
|
||||
use Illuminate\View\View;
|
||||
|
||||
|
@ -13,7 +14,7 @@ class ContactsController extends Controller
|
|||
/**
|
||||
* Show all the contacts.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
* @return View
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
|
@ -34,17 +35,15 @@ class ContactsController extends Controller
|
|||
/**
|
||||
* Show a single contact.
|
||||
*
|
||||
* @todo Use implicit model binding.
|
||||
*
|
||||
* @param string $nick The nickname associated with contact
|
||||
* @return \Illuminate\View\View
|
||||
* @param Contact $contact
|
||||
* @return View
|
||||
*/
|
||||
public function show(string $nick): View
|
||||
public function show(Contact $contact): View
|
||||
{
|
||||
$filesystem = new Filesystem();
|
||||
$contact = Contact::where('nick', '=', $nick)->firstOrFail();
|
||||
$contact->homepageHost = parse_url($contact->homepage, PHP_URL_HOST);
|
||||
$file = public_path() . '/assets/profile-images/' . $contact->homepageHost . '/image';
|
||||
|
||||
$filesystem = new Filesystem();
|
||||
$image = ($filesystem->exists($file)) ?
|
||||
'/assets/profile-images/' . $contact->homepageHost . '/image'
|
||||
:
|
||||
|
|
|
@ -73,9 +73,9 @@ class FeedsController extends Controller
|
|||
/**
|
||||
* Returns the blog JSON feed.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return array
|
||||
*/
|
||||
public function blogJson()
|
||||
public function blogJson(): array
|
||||
{
|
||||
$articles = Article::where('published', '1')->latest('updated_at')->take(20)->get();
|
||||
$data = [
|
||||
|
@ -106,7 +106,7 @@ class FeedsController extends Controller
|
|||
/**
|
||||
* Returns the notes JSON feed.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return array
|
||||
*/
|
||||
public function notesJson()
|
||||
{
|
||||
|
|
|
@ -7,11 +7,15 @@ use App\Models\Bookmark;
|
|||
use App\Models\Like;
|
||||
use App\Models\Note;
|
||||
use App\Services\ActivityStreamsService;
|
||||
use Illuminate\Http\Response;
|
||||
use Illuminate\View\View;
|
||||
|
||||
class FrontPageController extends Controller
|
||||
{
|
||||
/**
|
||||
* Show all the recent activity.
|
||||
*
|
||||
* @return Response|View
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
@ -19,8 +23,6 @@ class FrontPageController extends Controller
|
|||
return (new ActivityStreamsService())->siteOwnerResponse();
|
||||
}
|
||||
|
||||
$pageNumber = request()->query('page') ?? 1;
|
||||
|
||||
$notes = Note::latest()->get();
|
||||
$articles = Article::latest()->get();
|
||||
$bookmarks = Bookmark::latest()->get();
|
||||
|
|
|
@ -12,7 +12,7 @@ class LikesController extends Controller
|
|||
/**
|
||||
* Show the latest likes.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
* @return View
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
|
@ -24,8 +24,8 @@ class LikesController extends Controller
|
|||
/**
|
||||
* Show a single like.
|
||||
*
|
||||
* @param \App\Models\Like $like
|
||||
* @return \Illuminate\View\View
|
||||
* @param Like $like
|
||||
* @return View
|
||||
*/
|
||||
public function show(Like $like): View
|
||||
{
|
||||
|
|
|
@ -16,10 +16,10 @@ use MStaack\LaravelPostgis\Geometries\Point;
|
|||
|
||||
class MicropubController extends Controller
|
||||
{
|
||||
protected $tokenService;
|
||||
protected $hentryService;
|
||||
protected $hcardService;
|
||||
protected $updateService;
|
||||
protected TokenService $tokenService;
|
||||
protected HEntryService $hentryService;
|
||||
protected HCardService $hcardService;
|
||||
protected UpdateService $updateService;
|
||||
|
||||
public function __construct(
|
||||
TokenService $tokenService,
|
||||
|
|
|
@ -6,7 +6,7 @@ namespace App\Http\Controllers;
|
|||
|
||||
use App\Models\Note;
|
||||
use App\Services\ActivityStreamsService;
|
||||
use Illuminate\Contracts\View\Factory as ViewFactory;
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Response;
|
||||
|
@ -20,7 +20,7 @@ class NotesController extends Controller
|
|||
/**
|
||||
* Show all the notes. This is also the homepage.
|
||||
*
|
||||
* @return ViewFactory|View|Response
|
||||
* @return View|Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
|
@ -45,7 +45,11 @@ class NotesController extends Controller
|
|||
*/
|
||||
public function show(string $urlId)
|
||||
{
|
||||
$note = Note::nb60($urlId)->with('webmentions')->firstOrFail();
|
||||
try {
|
||||
$note = Note::nb60($urlId)->with('webmentions')->firstOrFail();
|
||||
} catch (ModelNotFoundException $exception) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
if (request()->wantsActivityStream()) {
|
||||
return (new ActivityStreamsService())->singleNoteResponse($note);
|
||||
|
|
|
@ -12,7 +12,7 @@ class PlacesController extends Controller
|
|||
/**
|
||||
* Show all the places.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
* @return View
|
||||
*/
|
||||
public function index(): View
|
||||
{
|
||||
|
@ -24,13 +24,11 @@ class PlacesController extends Controller
|
|||
/**
|
||||
* Show a specific place.
|
||||
*
|
||||
* @param string $slug
|
||||
* @return \Illuminate\View\View
|
||||
* @param Place $place
|
||||
* @return View
|
||||
*/
|
||||
public function show(string $slug): View
|
||||
public function show(Place $place): View
|
||||
{
|
||||
$place = Place::where('slug', '=', $slug)->firstOrFail();
|
||||
|
||||
return view('singleplace', ['place' => $place]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ class SearchController extends Controller
|
|||
/**
|
||||
* Display search results.
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
* @return View
|
||||
*/
|
||||
public function search(): View
|
||||
{
|
||||
|
|
|
@ -9,9 +9,9 @@ class SessionStoreController extends Controller
|
|||
/**
|
||||
* Save the selected colour scheme in the session.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return string[]
|
||||
*/
|
||||
public function saveColour()
|
||||
public function saveColour(): array
|
||||
{
|
||||
$css = request()->input('css');
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ class ShortURLsController extends Controller
|
|||
/**
|
||||
* Redirect from '/' to the long url.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function baseURL(): RedirectResponse
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ class ShortURLsController extends Controller
|
|||
/**
|
||||
* Redirect from '/@' to a twitter profile.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function twitter(): RedirectResponse
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ class ShortURLsController extends Controller
|
|||
/**
|
||||
* Redirect from '/+' to a Google+ profile.
|
||||
*
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function googlePlus(): RedirectResponse
|
||||
{
|
||||
|
@ -53,7 +53,7 @@ class ShortURLsController extends Controller
|
|||
*
|
||||
* @param string Post type
|
||||
* @param string Post ID
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @return RedirectResponse
|
||||
*/
|
||||
public function expandType(string $type, string $postId): RedirectResponse
|
||||
{
|
||||
|
|
|
@ -13,18 +13,18 @@ class TokenEndpointController extends Controller
|
|||
/**
|
||||
* The IndieAuth Client.
|
||||
*/
|
||||
protected $client;
|
||||
protected Client $client;
|
||||
|
||||
/**
|
||||
* The Token handling service.
|
||||
*/
|
||||
protected $tokenService;
|
||||
protected TokenService $tokenService;
|
||||
|
||||
/**
|
||||
* Inject the dependencies.
|
||||
*
|
||||
* @param \IndieAuth\Client $client
|
||||
* @param \App\Services\TokenService $tokenService
|
||||
* @param Client $client
|
||||
* @param TokenService $tokenService
|
||||
*/
|
||||
public function __construct(
|
||||
Client $client,
|
||||
|
@ -37,7 +37,7 @@ class TokenEndpointController extends Controller
|
|||
/**
|
||||
* If the user has auth’d via the IndieAuth protocol, issue a valid token.
|
||||
*
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function create(): JsonResponse
|
||||
{
|
||||
|
|
|
@ -60,6 +60,16 @@ class Place extends Model
|
|||
use Sluggable;
|
||||
use PostgisTrait;
|
||||
|
||||
/**
|
||||
* Get the route key for the model.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRouteKeyName()
|
||||
{
|
||||
return 'slug';
|
||||
}
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue