Laravel Version: 5.5.14
PHP Version: 7.1.10
Description:
When I try to POST with X-Requested-With='XMLHttpRequest' without CSRF-TOKEN I receive null message in response.
I add this code to App\Exceptions\Handler:
public function render($request, Exception $exception)
{
if($exception instanceof TokenMismatchException) {
abort(419, 'Token Mismatch OR page has expired due to inactivity.');
}
return parent::render($request, $exception);
}
Now I have Token Mismatch OR page has expired due to inactivity. message in response, but status text is: unknown status.
How can I set status text?
Return a \Illuminate\Http\Response and manually set the status code:
use Illuminate\Http\Response;
// snip
public function render($request, Exception $exception)
{
if($exception instanceof TokenMismatchException) {
return (new Response)->setStatusCode(419, "Token Mismatch OR page has expired due to inactivity.");
}
return parent::render($request, $exception);
}
The Status Code is part of the HTTP Protocol. 419 is not an official status Code see: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes therefor it is unknown.
So unknown status is right.
But if you really looking for the file where this is defined, go to:
/vendor/symfony/http-foundation/Response.php
Note:
If you change this file, than you have to do this after every update again.
Related
I asked a very specific question located here: Laravel 5 catching PayPal PHP API 400 errors on localhost:8000
As nobody could help I want to make it a more open question about catching a 400 error from the PayPal API.
I am making requests to PayPal, when a successful request is made everything works perfectly and I get a lovely response object, which I can work with and action accordingly.
When for instance incorrect card details are entered Laravel throws a 400 error and fails to catch the error for me to action accordingly.
Snippet:
try {
// ### Create Payment
// Create a payment by posting to the APIService
// using a valid ApiContext
// The return object contains the status;
$payment->create($this->_apiContext);
//will not catch here :( throws Laravel 400 error! want to redirect with message!
} catch (\PPConnectionException $ex) {
return Redirect::back()->withErrors([$ex->getMessage() . PHP_EOL]);
}
//if we get an approved payment ! This fires perfectly when succesful!!! woo!!
if($payment->state == 'approved') {
//if success we hit here fine!!!
} else {
//won't get here, dies before catch.
}
Here is the error in Laravel debug mode:
When I look in the PayPal API sandbox logs I should be getting a nice object so I can action accordingly.
{
"status": 400,
"duration_time": 60,
"body": {
"message": "Invalid request. See details.",
"information_link": "https://developer.paypal.com/webapps/developer/docs/api/#VALIDATION_ERROR",
"details": [
{
"field": "payer.funding_instruments[0].credit_card.number",
"issue": "Value is invalid."
}
],
"name": "VALIDATION_ERROR",
"debug_id": "XXXXXXXXXXXXXX"
},
"additional_properties": {},
"header": {
"Date": "Thu, 25 May 2017 14:44:43 GMT",
"paypal-debug-id": "2f88f18d519c3",
"APPLICATION_ID": "APP-XXXXXXXXXXXX",
"Content-Language": "*",
"CALLER_ACCT_NUM": "XXXXXXXXXXXXX"
}
}
If any Laravel wizard can help you would be my hero.
Nick.
Right guys,
It would appear that Laravel's default Exception method was interfering with the PayPal API PayPalConnectionException. So I modified the code to catch general Exception errors only as it contained all required error objects. The \ before Exception was critical! as it needs the correct namespace (in my case anyway, your application may be different).
try {
// ### Create Payment
// Create a payment by posting to the APIService
// using a valid ApiContext
// The return object contains the status;
$payment->create($this->_apiContext);
} catch (\Exception $ex) {
return Redirect::back()->withErrors([$ex->getData()])->withInput(Input::all());
}
This link that #rchatburn posted was highly useful, the application always seemed to catch at the point \Exception and NOT \PayPalConnectionException once I had everything namespaced correctly.
In my investigations I came across app/Exceptions/Handler.php. Here you can extend the render method to grab a PayPalConnectionException and handle the errors uniquely to that specific exception . See code:
//Be sure to include the exception you want at the top of the file
use PayPal\Exception\PayPalConnectionException;//pull in paypal error exception to work with
public function render($request, Exception $e)
{
//check the specific exception
if ($e instanceof PayPalConnectionException) {
//return with errors and with at the form data
return Redirect::back()->withErrors($e->getData())->withInput(Input::all());
}
return parent::render($request, $e);
}
Either work great, but for me it felt neater to just change the catch method to a lookout for a general Exception, where I am testing if a payment was successful.
Hope this helps anyone facing similar issues :D!!!
Nick.
I am trying to trap TokenMismatchException in Laravel’s Handler.php
When I mimic a csrf token exception by temporarily removing the token from the form, the local dev version of my site shows me:
TokenMismatchException in VerifyCsrfToken.php line 68:
But when I change the render() function in Handler.php to look for the exception and handle the error, then it doesn’t work. For instance, if I replace the default code with the below for testing, and take the csrf token from the form, the system returns my 'this was not a token problem' message, and not the 'token problem' message.
public function render($request, Exception $exception)
{
if($exception instanceof TokenMismatchException) {
return('token problem');
}else{
return('this was not a token problem');
}
return parent::render($request, $exception);
}
So, with the default code Laravel seems to recognize the TokenMismatchException, but with my simple test code above, it doesn’t. Can you explain to me what’s going on here?
Chances are it's crashing because the return is expecting a \Illuminate\Http\Response from render()
/**
* Render an exception into an HTTP response.
*
* #param \Illuminate\Http\Request $request
* #param \Exception $exception
* #return \Illuminate\Http\Response
*/
public function render($request, Exception $exception)
{
if($exception instanceof TokenMismatchException)
return response()->json('Token mismatch');
return parent::render($request, $exception);
}
Remember to use the correct class for the Exception
use Illuminate\Session\TokenMismatchException;
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'm looking to handle a MethodNotAllowedException. I've viewed other answers available on here that to create what i think should handle this in the exceptions/handler.php class. This is what i came up with.
public function render($request, Exception $e)
{
if ($e instanceof MethodNotAllowedHttpException) {
\Auth::logout();
\Session::flush();
return redirect()->('/')->withErrors(['error' => 'Something went wrong']);
}
return parent::render($request, $e);
}
However where i used to get an error before, all i recieve now is a blank page on the page where i usually recieve an error and a user is not logged out nor are they redirected. Am i placing this handler in the right place and if so, is the function shown below correct?
Thanks
I have project on Laravel 5, and I need to do async request via jQuery's $.ajax method.
Laravel can catch exception, and then it render special error template with it's own styles and markup.
But for async requests this html-code is redundant.
Is there a way to generate error response without laravel's markup on async requests?
I guess you wanted this to write the web service.
To handle this
Goto app/Exceptions/Handler.php :
And change this function
public function render($request, Exception $e)
{
return parent::render($request, $e);
}
to
public function render($request, Exception $e)
{
if ($this->isHttpException($e))
{
return $this->renderHttpException($e);
}
else
{
return parent::render($request, $e);
}
}
Also if you need to customize in the webview
Change your 404 blade \resources\views\errors\404.blade.php here