PHP throws an exception in subroutine stops working - php

I have a custom class with function, which calls a function of the Yii2 core BasisAuthentication. In the core module is defined, if the credentials are not valid,
throw new UnauthorizedHttpException('Your request was made with invalid credentials.');
With this, the whole request is ended. But I need to go further (because it is a REST request).
I've tried to prevent from that with
try {
$identity = $basic_Auth->authenticate($user, $request, null );
} catch (Exception $e) {
return null;
}
But this is not working. I don't want to adapt the core files of Yii. What can I do?

try {
$identity = $basic_Auth->authenticate($user, $request, null );
} catch (\Throwable $e) {
return null;
}

Related

How to rethrow an exception and call a method based on the original exception in php?

I am new to PHP and trying to active below:
I am catching multiple custom exceptions including standard exception.
I want throw these exceptions as another custom exception and based on the original exception I want to print a message.
example.php
try {
// Do something
} catch (CustomeException1 $ex) {
} catch (CustomException2 $ex) {
} catch (Exception $ex) {
}
I want to write something like FinalCustomException.php
class FinalCustomException extends Exception {
public static fromException(CustomException1 $ex) {
//print something
}
public static fromException(CustomException2 $ex) {
//print something
}
public static gotException() {
//call above fromException method based on the exception occurred
}
}
I am not sure How to do this. Can anyone please help me with this?
Thanks in advance.

Laravel throw ValidationException but not hitting destroy method's catch block?

I am trying to return a custom exception message using Laravel's ValidationException class. I have it successfully working in the following example:
public function store(Request $request)
{
$this->validate($request, CurrencyValidatorArrays::$store);
try {
$this->currenciesInstance->createOrUpdateCurrency($request->all());
return redirect()->route('currencies.index')
->with('success', 'Successfully created currency');
} catch (Exception $e) {
return redirect()->route('currencies.create')
->with('error', $e->getMessage());
}
}
where the exception is thrown from within createOrUpdateCurrency()
if(Currency::where('position', $data['position'])->where('id', '!=', $id)->exists()) {
throw ValidationException::withMessages([
'error' => ['Position value is already taken']
]);
}
This then passes the exception message back to my view for display.
However, I am trying to implement this somewhere else when trying to delete a company I am checking that no users exist first:
public function destroy($id)
{
try {
$this->companiesInstance->deleteCompany($id);
return redirect()->route('companies.index')
->with('success', 'Successfully deleted company');
} catch (Exception $e) {
return redirect()->route('companies.index')
->with('error', $e->getMessage());
}
}
Inside of deleteCompany():
$company = Company::find($id);
if($company->users()->exists()){
throw ValidationException::withMessages([
'error' => ['Position value is already taken']
]);
}
For some reason this doesn't hit my catch block from the main destroy method,if I change the exception type to ValidationException from Exception I can access and see the exception object but not in the way I can in the Store() methods version. Any ideas what is going on here?
UPDATE:
So I have a some what of a workaround:
To get by the exception type issue I used:
catch (ValidationException | Exception $e) { ...
But that still does not help when accessing the exception messages as when it's of type ValidationException the default constructor validation message is returned from getMessage() and not my specified one.
PHP 7 handles exceptions a bit differently. You can read it here.
Coming back to your code, you have to try and catch object of Throwable instead of Exception.
try
{
// Code that may throw an Exception or Error.
}
catch (Throwable $t)
{
// Code that handles the error
}
Hope this helps.

try-catch in function and in main script?

I am looking to get some advice on best practice for throwing exceptions and catching them. I am using a 3rd party library for connecting to Amazon mws API. This library already throws exceptions which I am catching within a function.
My question is, should this function pass the exception onto the main script by using a try-catch? e.g.
function myFunction() {
try {
$obj = new Object();
$obj->makeCall();
return $obj->getData();
} catch (Exception $ex) {
throw new Exception('There was a problem with the library '.$ex->getMessage());
}
}
then in the main script;
try {
//make the call
$response = myFunction();
} catch (Exception $e){
//log error
$logger->error("log error");
}
If you are catching the exception in the main script, you don't need to catch it in your function myFunction until you need to do some processing in your function.
The control will return to the exception being catched in the main script if any of it's children or children's children and so on throw an exception.

How to reach the exception block

So I am messing around with symfony router component and I created a small wrapper.
One thing that came up was how do I get a request to throw a 500 in unit tests? The method in question is:
public function processRoutes(Request $request) {
try {
$request->attributes->add($this->_matcher->match($request->getPathInfo()));
return call_user_func_array($request->attributes->get('callback'), array($request));
} catch (ResourceNotFoundException $e) {
return new RedirectResponse('/404', 302);
} catch (Exception $e) {
return new RedirectResponse('/500', 302);
}
}
And the test in question is:
public function testFiveHundred() {
$router = new Router();
$router->get('/foo/{bar}', 'foo', function($request){
return 'hello ' . $request->attributes->get('bar');
});
$response = $router->processRoutes(Request::create('/foo/bar', 'GET'));
$this->assertEquals(500, $response->getStatusCode());
}
Right now the test will fail because we are defined and the status code will be 200. Is there something special I can do to the Request object I create, to make it throw a 500?
I think you got several options here you can play with:
Decide that a specific path will always throw an exception.
This will force you to make some changes in your code.
public function processRoutes(Request $request) {
...
if ($request->getRequestUri() == '/path/that/throws/exception') {
throw Exception('Forced to throw exception by URL');
}
...
}
public function testFiveHundred() {
...
$response = $router->processRoutes(Request::create('/path/that/throws/exception', 'GET'));
...
}
Make a DummyRequest object that will extends your original Request class and make sure this object will raise an Exception (for example - you know for sure that you use the getPathInfo(), so you can use this).
class DummyRequest extends Request {
public function getPathInfo() {
throw new Exception('This dummy request object should only throw an exception so we can test our routes for problems');
}
}
public function testFiveHundred() {
...
$dummyRequest = new DummyRequest();
$response = $router->processRoutes($dummyRequest);
...
}
Since the function getRequestUri of our $dummyRequest throws an exception, your call to $router->processRoutes will have our dummy to throw that exception.
This is a general idea, you would probably need to play a bit with the namespaces and the functions there (I didn't test it, however this should work).

How to set a HTTP_Exception_404

I am using kohana 3.2 and kohana-error module is working fine, when the page does not exist.
But I have this situation: the page exist, but no data is coming, because the data does not exist. I am using the route param to check de database.
So I did this,
if($response )
{
return $response;
} else {
throw new HTTP_Exception_404('Page Not Found');
}
If there are data return, if not, create a ‘Page Not Found’ and I supose it will be caught by the kohana-error module but it is not....
Is that possible? Is this the right approach?
In your index.php, you do the following:
$request = Request::factory();
try
{
$response = $request->execute();
if (!$response->body())
{
throw new HTTP_Exception_404();
}
}
catch (Exception $exc)
{
if ($exc instanceof HTTP_Exception_404)
{
$response = Request::factory('your/404error/controller')->execute();
}
else
{
// rethrow exception
throw $exc;
}
}
echo
$response
->send_headers()
->body();
That way, you can execute a controller for each HTTP exception, or you can use a catch all 404 page for all exceptions (50x and 40x errors)

Categories