How can i catch Container exceptions? - laravel

I want to be able to catch container binding exceptions but it doesn't seem to work.
If i have this code:
try {
$instance = app()->make('SomeNonExistingBinding');
} catch (Exception $e) {
// handle failure
}
But somehow the thrown Exception is being caught in the Illuminate\Routing\Pipeline::prepareDestination() method that AFAIK converts the exceptions in HTTP responses, instead of my try-catch block.
Can someone help me on this, please?
Thanks in advance.

Related

ParallelFlux doOnNext how to handle Exception

In my project I have this:
ParallelFlux<Device> flux = Flux.fromIterable(children)
.delayElements(Duration.ofMillis(10))
.parallel(18)
.runOn(Schedulers.elastic(), 10)
.doOnNext(c -> recursiveValidationThroughoutChildren(c, tracker)
});
Where recursiveValidationThroughoutChildren is a method with this declaration:
boolean recursiveValidationThroughoutChildren(Device d, NodeChangesTracker tracker) throws Exception;
What I don't understand is how to handle the exception thrown by this last method. I would like the exception to be propagated outside the ParallelFlux.
Is it possible? What is the correct way to handle it?
I followed the link #Rozart suggested, but I could not apply the solution as it is explained. I had to change it a bit:
ParallelFlux<Device> flux = Flux.fromIterable(children)
.delayElements(Duration.ofMillis(10))
.parallel(18)
.runOn(Schedulers.elastic(), 10)
.doOnNext(child -> {
try {
recursiveValidationThroughoutChildren(child, tracker);
} catch (Exception ex) {
Flux.error(ex);
}
});
The change is needed because the ParallelFlux does not support the "handle" method, so I had to add a try catch and relaunch the exception with a Flux.error.
I don't know if it is good practice, but it is the only way I got it work.

How to fix Sonar Violation: Invoke methods only conditionally and Either Log or rethrow the exception

I have the below statements in my code which violates some Sonar Rules.
LOG.info("Fetched: {}", mapper.writeValueAsString(requests));
This one shows Invoke method(s) only conditionally for mapper.writeValueAsString(requests).
}catch (Exception e) {
LOG.error("Exception occurred while trying to fetch requests", e);
throw new GenericException(Error.FETCH_REQUEST_ERR_001.name(), e.getMessage(), Error.FETCH_REQUEST_ERR_001.value());
}
This one shows Either log this exception and handle it, or rethrow it with some contextual information. rule violation.
Any idea on how to resolve these. Appreciate any help.
I use IntelliJ and in a similar situation as yours SonarLint plugin accepted the following fix for me:
if(LOG.isInfoEnabled() && mapper != null){
LOG.info("Fetched: {}", mapper.writeValueAsString(requests)); // Your code
}

Why finally block exists?

In most programming languages, there is a finally block that can be placed after try or catch block like this :
try {
sensitiveFunction();
} catch (Exception e) {
executedWhenFailed();
} finally {
alwaysExecuted();
}
But we can execute the same code without finally block like that :
try {
sensitiveFunction();
} catch (Exception e) {
executedWhenFailed();
}
alwaysExecuted();
So, why does finally block exist? Anyone have an example that finally block is required ?
Thanks
Even these examples aren't equivalent: if sensitiveFunction() throws something which doesn't extend Exception but Error instead, alwaysExecuted won't be executed without finally (please don't try to "fix" this by catching Throwable).
Or say executedWhenFailed() itself throws an exception: it's quite common to rethrow an exception from a catch block after adding some information. Again, alwaysExecuted() won't be executed in the second snippet.
Or suppose you have return sensitiveFunction(); instead of just a call. Etc. etc.
finally exists so that code can always be run, without regard to if you caught the exception or not.
Sometimes you want to just use try and finally together:
allocate()
try:
do_something_with_allocated()
finally:
deallocate()
In the above example, it lets you 100% confidently clean up a resource that was opened above without regard for any exceptions that may be propagating up.
If you throw a new exception in your catch block, you will eventually (after that exception has been handled) end up in your finally block. But not in the line after your catch.
Just throw an exception in executedWhenFailed, in your first example alwaysExecuted will be executed, in the second it wil not.
The finally block is executed even if there is a return statement in the catch() block.
(Example in JavaScript)
function foo() {
try {
throw "first"
} catch(err){
console.log(err)
return "third"
} finally {
console.log("second") // Called before return in catch block
}
return "Never reached"
}
console.log(foo())

Laravel 5.5 Try / Catch is not working it's execute the exception handle

I am working with laravel 5.5 I have written a code with try and catch exception. But Try / catch is not manage exception handling. Exception execute on the Exception/handle.php
Here is code I am following
try {
App\Models\justDoIt::find(1);
} catch (\Exception $ex) {
dd($ex);
report($ex);
return false;
}
I would like to know why catch is not executed and error is display from the handle.php in report()
Here is the handle.php code
public function report(Exception $exception) {
echo "Handle";
dd($exception);
parent::report($exception);
}
Result
Handle
FatalThrowableError {#284 ▼
#message: "Class 'App\Http\Controllers\App\Models\justDoIt' not found"
#code: 0
#file: "D:\xampp7\htdocs\homeexpert_nik\app\Http\Controllers\HomeController.php"
#line: 21
#severity: E_ERROR
trace: {▶}
}
Result will show from the handle.php file.
Your code is throwing an error, not an exception. You're trying to use a class that doesn't exist and PHP is complaining about it by throwing a FatalThrowableError.
In PHP 5, this code would have resulted in a fatal error message being rendered in the browser, however in PHP 7 (Which is required for Laravel 5.5), PHP now throws errors just like they were exceptions. This allows applications to catch these errors, just like exceptions using try/catch blocks.
The reason the error is escaping your try/catch block is that an error is not an Exception, or a child of it. The object being thrown is an Error. Both the Exception and Error classes implement a common interface, Throwable.
Throwable
- Exception
- Error
Laravel's exception handler is written to catch both of these classes in order to display the error page you're seeing.
If you were to change your code to the following, you would find that the } catch (Throwable $e) { block should be executed:
try {
App\Models\justDoIt::find(1);
} catch (\Exception $ex) {
dd('Exception block', $ex);
} catch (\Throwable $ex) {
dd('Throwable block', $ex);
}
For more information on this, see here.
An added extra: If you're wondering what the issue is with your code, it's because you likely forgot to use your model class in your controller:
use App\Models\justDoIt;

Unable to throw httpResponseException

When I try to throw the below forbidden ResponseException from my controller. An exception stating "Processing of the HTTP request resulted in an exception. Please see the HTTP response returned by the 'Response' property of this exception for details." is catched in the catch block of the controller method. Need help in resolving this
throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Forbidden));
Just change your controller implementation to re-throw if it's an HttpResponseException:
try
{
// action implementation
}
catch (Exception e)
{
if (e is HttpResponseException)
{
throw e;
}
// error handling logic
}
But the better answer is that #1 - you should avoid be catching all exceptions, that's bad practice. And #2 - you should use an exception filter instead to do your error handling and not catch exceptions yourself.

Resources