I'm new to Lumen and want to create an app with this framework. Now I have the problem that if some user enters a wrong url => http://www.example.com/abuot (wrong) => http://www.example.com/about (right), I want to present a custom error page and it would be ideal happen within the middleware level.
Furthermore, I am able to check if the current url is valid or not, but I am not sure how can I "make" the view within the middleware, the response()->view() won't work.
Would be awesome if somebody can help.
Seeing as errors are handled in App\Exceptions\Handler, this is the best place to deal with them.
If you are only after a custom 404 error page, then you could do this quite easily:
Add this line up the top of the Handler file:
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
Alter the render function to look like so:
public function render($request, Exception $e)
{
if($e instanceof NotFoundHttpException){
return response(view("errors.404"), 404);
}
return parent::render($request, $e);
}
This assumes your custom 404 page is stored in an errors folder within your views, and will return the custom error page along with a 404 status code.
You may want to add this so that when for example blade blows up the error page hander will not throw a PHP error.
public function render($request, Exception $exception)
{
if (method_exists('Exception','getStatusCode')){
if($exception->getStatusCode() == 404){
return response(view("errors.404"), 404);
}
if($exception->getStatusCode() == 500){
return response(view("errors.500"), 404);
}
}
return parent::render($request, $exception);
}
I am using Lumen 8.x version and below solution worked for me:
File path: ▸ app ▸ Exceptions ▸ Handler.php
public function render($request, Throwable $exception)
{
// start custom code
if($exception->getStatusCode() == 404){
return response(view("errors.404"), 404);
}
if($exception->getStatusCode() == 500){
return response(view("errors.500"), 404);
}
// end custom code
return parent::render($request, $exception);
}
Do not forget to create errors folder at /resources/views/errors and create the below 2 new files in errors folder:
404.blade.php
500.blade.php
and add html tags and messages in those files what you want to add.
Happy to help you. Thanks for asking this question.
I faced the same situation. response(view("errors.404"), 404)did not work for me, so I changed it as follows:
public function render($request, Exception $exception)
{
if($exception instanceof NotFoundHttpException){
return response(view('errors.404')->render(), 404);
}
return parent::render($request, $exception);
}
Related
How to call custmo error in controller, that after to show in template?
For example, I have condition:
if($id == 500){
// call error
}
If you want to call just the error in the controller and abort, you do
abort(500, 'Internal error');
If you want to return an error
return redirect()->back()->withErrors(['error' => 'was 500']);
You can do this by catching the error in the Handler (app/Exceptions/Handler.php), something like this:
public function render($request, Exception $e){
// other errors here by your wish
// custom error message
if ($e instanceof \ErrorException) {
return response()->view('errors.500', [], 500);
}else{
return parent::render($request, $e);
}
return parent::render($request, $e);
}
Note that you need 500 template in resources/views/errors/500.blade.php (create if it doesnt exist, and fill if with your data or iformation about the exception)
For example, I use:
return User::findOrFail($id);
When row does not exist with $id I get exception.
How I can return this exception in Json response? It returns HTML Laravel page now.
I need something like as:
{"error", "No query results for model"}
From their documentation:
Sometimes you may wish to throw an exception if a model is not found. This is particularly useful in routes or controllers. The findOrFail and firstOrFail methods will retrieve the first result of the query. However, if no result is found, a Illuminate\Database\Eloquent\ModelNotFoundException will be thrown.
So, you can either catch that exception, or go with the simple Find method. It will return false if not found, so you can handle it accordingly.
return User::find($id);
UPDATE:
Option 1:
try {
return User::findOrFail($id);
} catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
return json_encode(['error' => 'No query results for model']);
}
Option 2:
$user = User::find($id);
if($user) {
return $user;
}
return json_encode(['error' => 'No query results for model']);
You can handle various types of exceptions, that exception can be handle with a ModelNotFoundException in this case
try{
$user = User::findOrFail($id);
}catch(ModelNotFoundException $e){
return response()->json(['error' => 'User not found'], 400);
}
And there's another way to catch various types of exceptions in the Handler.php located on app/Exceptions/Handler.php there you can catch the exceptions and return whatever you want inside the render function.
For example insede that function you can add this before the return parent::render($request, $e):
if($e instanceof ModelNotFoundException)
{
return new Response(['message' => 'We haven\'t find any data'], 204);
}
You should look in render method of Handler file. You can test exception class here and depending on it return different response in Json format
I use Laravel 5.2
I wanted to change this error :
Whoops, looks like something went wrong.
first please see : Laravel
I created a new file resources/views/errors/404.blade.php but my app error didn't change !
it change just when not found url at route but when insert url injection in to $_GET it show "whoops .." yet
for example work for this link : http://domain.com/dgdgergehrhddg54d6g8
but not working for this injection : http://domain.com/listmanage=8 insert 9 instens of 8
error message when debug is true :
ErrorException: file.php line 215
Trying to get property of non-object
You are viewing that error page because of the environment you are into.
As default, for local environments, the "Whoops" format is shown.
For Production environments, the error/x.blade.php files are used.
To customize this you simply go to: ./app/Exceptions/Handler.php
And modify the render function. You can do something like this:
public function render($request, Exception $e)
{
// If an ErrorException is received and this enviroment is local
if ($e instanceof \ErrorException && app()->environment() == 'local') {
// Show customized page
return response()->view('errors.404', [], $e->getCode());
}
return parent::render($request, $e);
}
Cheers :)
on Larvel 5.2 on your app/exceptions/handler.php just extend this method renderHttpException ie add this method to handler.php
/**
* Render the given HttpException.
*
* #param \Symfony\Component\HttpKernel\Exception\HttpException $e
* #return \Symfony\Component\HttpFoundation\Response
*/
protected function renderHttpException(HttpException $e)
{
// to get status code ie 404, 503, 500
$status = $e->getStatusCode();
if (view()->exists("errors.{$status}")) {
return response()->view("errors.{$status}", ['exception' => $e], $status, $e->getHeaders());
} else {
return $this->convertExceptionToResponse($e);
}
}
Hope that helps.
I am using Laravel version 5.2 and don't know how to redirect Laravel default page to my template 404 page
use abort(404);
Some exceptions describe HTTP error codes from the server. For
example, this may be a "page not found" error (404), an "unauthorized
error" (401) or even a developer generated 500 error. In order to
generate such a response from anywhere in your application, use the
following:
abort(404);
If you invoke abort(404); anywhere in your route or controller it will throw HTTPNotFoundException which looks for a blade template to display in resources/views/errors/ directory with the filename same as the error code.
Example:
in your app/Http/routes.php
Route::get('/test', function(){
return abort(404);
});
in your resources/views/errors/ directory create 404.blade.php, notice the name of the file corresponds with the abort(404);
Reference: https://laravel.com/docs/5.2/errors#http-exceptions
Modify app/Exceptions/Handler.php and add some lines as below:-
public function render($request, Exception $e)
{
if ($e instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException)
{
return redirect('/');
}
return parent::render($request, $e); }
Use your route name in place of / where you want to redirect.
Create a view and set this code in app/Exceptions/Handler.php :
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
.
.
.
public function render($request, Exception $exception)
{
if($exception instanceof NotFoundHttpException)
{
return response()->view('missing', [], 404);
}
return parent::render($request, $e);
}
in the /resources/views/errors directory there is a 404 page
edit this page and you can make it look like you want
I want to set different view blade template for different exception and also pass the errors on the following page. I tried out the following code but it's not working. It always goes to the else portion of the code and run the parent::render($request, $e);code.
public function render($request, Exception $e)
{
if ($this->isHttpException($e))
{
if($e instanceof InvalidArgumentException)
{
return response()->view('front.missing', [], 404);
}elseif($e instanceof ErrorException){
return response()->view('front.missing2', [], 404);
}
return $this->renderHttpException($e);
}else{
if($e instanceof InvalidArgumentException)
{
return response()->view('errors.204', []);
}
return parent::render($request, $e);
}
}
Where is the problem here and what I will do now?
InvalidArgumentException is not a child class of HttpException, so it always goes to the else portion.