any way to handle exceptions for model type parameters?
public function removeItem(Item $item){
//code...
}
I get a 404 error screen when the function receives an id that does not exist, I would prefer to launch a simple alert that does not destroy the form.
Related
I am trying to implement exception handling in my application. For this Laravel framework has its own mechanism to handle the exception using report and render method. But to implement exception I need to track the source from where the exception has been raised e.g. specific page, route etc. For this I need to pass the url to report and render method but unable to do so. What needs to be done in order to implement this in below report and render function.
public function report(Exception $e)
{
parent::report($e);
}
public function render($request, Exception $e)
{
/* Token mismatch Exception handler start */
if ($e instanceof \Illuminate\Session\TokenMismatchException) {
return response()->view('errors.sessionExpire', [], 500);
}
/* Token mismatch Exception handler start */
return parent::render($request, $e);
}
As you can see from your own example, you have an instance of Request in the argument list. And Request has all request-specific details like current route, URL and so on.
$request->url(); // Current request URL
$request->fullUrl(); // With query parameters
$request->route(); // Get the route closure for this request path
You can also create your own exception classes that accept as many parameters as you wish!
And the less comfortable way already mentioned – you could go through the exception trace.
You need to use Exception::getTrace
var_dump($e->getTrace());
above line will give you all details regarding exception.
public function report(Exception $e){
echo '<pre>'; // add this line
print_r($e->getTrace()); // add this line
parent::report($e);
}
I have a repository that throws an exception if it can't find a record in the database. Rather than redirect to another page I just want to display a warning alert as the record is not critical to the page but is an "exceptional event".
It's probably best to demonstrate with code:
// FxRateRepositoy
public function getRate(/** args **/)
{
$rate = FxRate::where(.... //query to get the rate
if (!rate)
throw new NonExistentCurrencyException(//message);
return $rate;
}
In my start/global.php I have a handler:
App::error(function(NonExistentCurrencyException $e)
{
Session::flash('alert', $e->getMessage());
return \\ ??
});
What to return? I must return a response or the exception continue uncaught. I want to continue to the intended page but with the alert flashed in the session. Is this possible without having to use try catch blocks in every place this method is called?
Ass an additional question, assuming this exception may be thrown multiple times in one request, what's the best way to accumulate alert messages and display them? I'm thinking something akin to the validation messageBag. Can I just use the global $errors variable or should I create a new, specific messagebag for this purpose?
The problem is that if you return nothing from App::error Laravel will display it's default error page. On the other side you can't return a response because you don't know what response it should be in the error handler.
I suggest you handle it in the controller itself.
You can catch the exception there and flash the message or don't throw an exception at all:
$rate = FxRate::where(.... //query to get the rate
if (!rate){
Session::flash('alert', 'Whoops');
}
Also the findOrFail() and firstOrFail methods might be of use. They throw an ModelNotFoundException if the query yields no results:
try {
$rate = FxRate::where(....)->firstOrFail()
// and so on
} catch (Illuminate\Database\Eloquent\ModelNotFoundException $e){
Session::flash('alert', 'Whoops');
}
As for a messages system, take a look at the laracasts/flash package
I'm trying to do a redirect from my service class. I don't want to return the url to the caller because it's not being accessed directly from controller and it should return other data in some cases.
However I found that i can do the redirect this way:
Redirect::away('http://someexternalurl.com')->send();
This seems to work fine - the user gets redirected to the url I entered. The problem is that in this case the app "lives on" so following commands get executed. That's not what I need.
If I die(); immediately after that my session changes don't seem to be "saved".
Is there a way to make a redirect and stop the App immediately after that without simply "killing" it?
Basically is there a way to rewrite this code
Session::forget('myval');
Redirect::away('http://someexternalurl.com')->send();
mail('my#mail.com', 'Test', 'Still running');
So that myval would be gone from the session, the user would be redirected to the url and mail would not be sent (actually anything after the redirect shouldn't be executed)?
Thank you
The solution is to throw an Exception and adapt the render method of the Exception Handler.
In Your Controller:
// app/Controllers/DashboardController.php
public function index()
{
\App\Services\Test::test();
return view('dashboard');
}
My example service :
// app/Services/Test.php
<?php
namespace App\Services;
class Test {
public static function test() {
throw new \App\Exceptions\TestException('test');
}
}
In your Exception Handler :
// app/Exceptions/Handler.php
public function render($request, Exception $exception)
{
if ($exception instanceof TestException) {
return redirect(url('/?error=' . $exception->getMessage()));
}
return parent::render($request, $exception);
}
My example Exception (you can name it whatever you want), it just needs to extend the default Exception.
<?php
namespace App\Exceptions;
class TestException extends \Exception {
}
It looks like you just need to return on you Redirect?
return Redirect::away('http://someexternalurl.com')->send();
Here's the solution for Laravel 5.2. I reckon it would be work at all 5.*
abort(301, '', ['Location' => 'http://antondukhanin.ru']);
methodThatWouldntBeExecuted();
the function throws HttpException, so that will interrupt execution of any next commands
Here is the exception I got:
No result was found for query although at least one row was expected.
I am basically getting that exception when a user id is not found in database.
Here is what my route looks like:
localhost/../user/18
and the code in my controller:
public function showAction(User $user){
// ..
}
I know I can use the kernel event exception to handle this, but is there an easier way to catch an exception generated by the ParamConverter?
In some cases it's useful to throw exception manually if object not found. You can tell action skip throw exception if entity not found by adding default value to param.
Example:
public function showUser(User $user = null) {
if (empty($user)) {
throw new CustomExceptionYouWant();
}
...
}
You can create your user ParamConverter by implementing ParamConverterInterface and inside it, create methods you can use as a custom exception or do other processing.
This a good exemple of what you want to create Custom ParamConverter
This is a follow up question of this question, which is not really important.
I have written the following front controller plugin:
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
$response = $this->getResponse();
$monitor = Zend_Registry::get('monitor');
if ($response->isException())
{
$monitor->log($response);
}
}
Where $monitor is an instance of a custom DB logging class (extending Zend_Log).
In the log method of the Monitor I loop over the Array of Zend_Exceptions returned by $response->getException().
For testing purposes I through an exception in an action:
throw new Zend_Exception('the big test', 555);
Most things work as expected, the Exception is written to the database.
Question
But, it's written twice. Why?
Because the dispatch loop is called twice. First for the current action and then for default:error:error :) Place the log into dispatchLoopShutdown() method