Globally catch ModelNotFoundException on Laravel 5 - laravel

I am trying to catch the ModelNotFoundException globally from the app\Exceptions\Handler class, so to not have to check for it on every single controller.
But it does not work, although it works fine from inside a controller:
try {
$asset = Asset::findOrFail($asset_id);
} catch (Exception $e) {
if ($e instanceof ModelNotFoundException)
{
$model = explode('\\', $e->getModel());
return $this->respondWithRecordNotFound(end($model) . ' record not found');
}
return $this->respondWithGeneralError($e->getMessage());
}
app\Exceptions\Handler:
public function render($request, Exception $exception)
{
if ($exception instanceof ModelNotFoundException)
{
$model = explode('\\', $exception->getModel());
return $this->respondWithRecordNotFound(end($model) . ' record not found');
}
return parent::render($request, $exception);
}

I am not sure what your respondWithRecordNotFound is doing. I guess the issue might lie there.
In any case, I just tried it out and this works for me. In App\Exceptions\Handler.php#render
if ($e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
return response()->view(
'errors.404',
["message" => $e->getModel() . ' record not found'],
404
);
}

Just make sure you have added the use in the Handler.php
use \Illuminate\Database\Eloquent\ModelNotFoundException;

Related

Only load route with existent parametre

Im doing a crud, i want to show item data using id, i have this in web.php:
Route::get('update/{id}', 'CrudController#update');
How can I deny that the user changes the id in the path to one that does not exist? That shows only those that exist and those that do not, that do not load?
In your update method, you can do the following:
public function update($id)
{
MyModel::findOrFail($id);
//...perform other actions
}
It will throw a 404 response if the requested $id is a non-existent one.
Then you can catch it if you want in the render() method of app\Exceptions\Handler.php:
use Illuminate\Database\Eloquent\ModelNotFoundException;
.
.
.
public function render($request, Exception $exception)
{
if ($exception instanceof ModelNotFoundException) {
if ($request->wantsJson()) {
return response()->json([
'data' => 'Resource not found'
], 404);
} else {
abort(404);
}
}
return parent::render($request, $exception);
}
Or, If you do not want to go through all the trouble of configuring it in the handler, you could also do:
public function update($id)
{
if (! $model = MyModel::find($id)) {
abort(404);
}
//...perform other actions with $model
}
The abort(404) method takes the user to the default Page not found page of laravel, which is an appropriate thing to do.

Is there anyway to show SQLSTATE[HY000][1049] CUSTOM exception in laravel blade ?

I've recently installed laravel, everything is working fine. All i'm trying to achieve is to show Custom db error messages or callback methods.
If i add/create database to sql server,it will work fine but i want to make it like wordpress installation.
If anyone can give me reference to some article that would be great.
Go to app/Exceptions/Handler.php and override the method like below:
public function render($request, Exception $e)
{
if (method_exists($e, 'render') && $response = $e->render($request)) {
return Router::toResponse($request, $response);
} elseif ($e instanceof Responsable) {
return $e->toResponse($request);
}
$e = $this->prepareException($e);
if ($e instanceof HttpResponseException) {
return $e->getResponse();
} elseif ($e instanceof AuthenticationException) {
return $this->unauthenticated($request, $e);
} elseif ($e instanceof ValidationException) {
return $this->convertValidationExceptionToResponse($e, $request);
} elseif ($e instanceof QueryException){
return $this->customQueryException($e, $request);
}
return $request->expectsJson()
? $this->prepareJsonResponse($request, $e)
: $this->prepareResponse($request, $e);
}
And then add the custom message exception.
private function customQueryException(QueryException $e, $request){
return response('Your custom message here');
}

How to Redirect the page if the url has a different parameters or the route doesn't exist? in laravel

how to redirect the page if the route doesn't exist like
'sitename.me/asdasdas'
because when I'm trying to do this
the NotFoundHttpException will show up.
please help me thanks
You can change the app/Exceptions/Handler.php for this purpose. Replace the render() and unauthenticated() function with the following.
public function render($request, Exception $exception) {
if ($this->isHttpException($exception)) {
switch ($exception->getStatusCode()) {
// not found
case 404:
return redirect()->guest(your redirect url));
break;
// internal error
case '500':
return redirect()->guest(your redirect url));
break;
default:
return $this->renderHttpException($exception);
break;
}
} else {
return parent::render($request, $exception);
}
}
protected function unauthenticated($request, AuthenticationException $exception) {
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest(your redirect url);
}
To redirect to external domains, use the following:
return redirect()->away('http://sitename.me/asdasdas');
To redirect to an internal URI, use:
return redirect('admin/dashboard');
To redirect to an application route, use:
return redirect()->route('admin.dashboard');
For further reference, have a look at the responses (redirects) documentation.
let me explain some details i have faced, Laravel throw common exception throw Handler.php file in app/Exceptions folder. In this file we have report function that throw common exception using render function.
public function report(Exception $exception)
{
if ($exception instanceof \League\OAuth2\Server\Exception\OAuthServerException){
$this->render(null,$exception);
} else {
parent::report($exception);
}
}
Above is an report function that throw any exception to render function specified below
public function render($request, Exception $exception)
{
if($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException){
// return Helper::responseJson(null,'header','Page Not Found',404);
} else if ($exception instanceof ScopeHandler) {
return Helper::responseJson(null,'header','Unauthorized',401);
} else if ($exception instanceof \League\OAuth2\Server\Exception\OAuthServerException){
return Helper::responseJson(null,'token','Unauthorized',401);
} else if ($exception instanceof ModelNotFoundException) {
// return Helper::responseJson(null,'header','Model Not Found',404);
} else if ($exception instanceof \Illuminate\Database\QueryException){
// return Helper::responseJson(null,'header','Query Exception',400);
} else if ($exception instanceof \Swift_TransportException){
return Helper::responseJson(null,'header','Mail send Exception',400);
}else if ($exception instanceof ConnectionFailedException){
return Helper::responseJson(null,'header','Connection Exception',400);
}
/* else if($exception instanceof \Symfony\Component\Debug\Exception\FatalErrorException){
return Helper::responseJson(null,'header','PHP config Exception',400);
} */
return parent::render($request, $exception);
}
the above example of render function we used for throw exception using json format. we can redirect to specific page or we can do any functionality when these error thrown.

Laravel always return the error bag of an Validation error in json

I'm developing an api that should also provide messages about the validation problems.
When "hardcoding" validators I'm doing something like this
if ($validator->fails()) {
return response()->json($validator->errors(), 400);
}
this works nice - however I want a "generic" solution to basically catch all ValidationExceptions and do the same as above.
I already tried to play around in the render function of Handler.php
public function render($request, Exception $exception)
{
$message = $exception->getMessage();
if (is_object($message)) {
$message = $message->toArray();
}
if ($exception instanceof ValidationException) {
return response()->json($message, 400);
}
...
}
However I can't find a proper way of returning the actual relevant data that I want
It's kinda dumb - actually laravel already provided what I want. Handler extends ExceptionHandler which does:
public function render($request, Exception $e)
{
$e = $this->prepareException($e);
if ($e instanceof HttpResponseException) {
return $e->getResponse();
} elseif ($e instanceof AuthenticationException) {
return $this->unauthenticated($request, $e);
} elseif ($e instanceof ValidationException) {
return $this->convertValidationExceptionToResponse($e, $request);
}
return $this->prepareResponse($request, $e);
}
and convertValidationExceptionToResponse :
if ($e->response) {
return $e->response;
}
$errors = $e->validator->errors()->getMessages();
if ($request->expectsJson()) {
return response()->json($errors, 422);
}
return redirect()->back()->withInput(
$request->input()
)->withErrors($errors);
So exactly what I wanted
public function render($request, Exception $exception)
{
if ($request->wantsJson() && (str_contains('api/v1/register', $request->path())) || (str_contains('api/v1/login', $request->path())) ) {
$errors = null ;
if($exception->validator){
$errors = $exception->validator->errors();
}
return response()->json([
'status' => 422,'success'=> false,'message'=>''. $exception->getMessage() ,'error'=> "" . $errors
], 422);
}
return parent::render($request, $exception);
}

Laravel 5 Error Handling

I am using Laravel 5 and I am trying to make custom 404 page and custom Exception handling, but I can't figure out where to put my code. Some time ago there was an ErrorServiceProvider that no longer exists. Can anyone give me some pointers?
EDIT: I saw they have added a Handler class in the App/Exception folder but that still seems not the right place to put it because it does not follow at all the laravel 4.2 App::error, App::missing and App::fatal methods. Anyone has any ideas?
Use app/Exceptions/Handler.php render method to achieve that. L5 documentation http://laravel.com/docs/5.0/errors#handling-errors
public function render($request, Exception $e)
{
if ($e instanceof Error) {
if ($request->ajax()) {
return response(['error' => $e->getMessage()], 400);
} else {
return $e->getMessage();
}
}
if ($this->isHttpException($e)) {
return $this->renderHttpException($e);
} else {
return parent::render($request, $e);
}
}
Here is how to customize your error page while complying with the APP_DEBUG setting in .env.
app/Exceptions/Handler.php
public function render($request, Exception $e)
{
if ($this->isHttpException($e))
{
return $this->renderHttpException($e);
}
else
{
if (env('APP_DEBUG'))
{
return parent::render($request, $e);
}
return response()->view('errors.500', [], 500);
}
}

Resources