why having try/catch in corutineAScope block still crash by the exception caught - exception

fun main() = runBlocking {
coroutineScope {
val child = async {
Log.e("+++", "+++ in async{}, throw exception , ${Thread.currentThread().name}")
throw Exception("test exception with await() in async")
}
try {
child.await()
} catch(ex: Throwable) {
Log.e("+++", "+++ child.await() caught exception $ex, ${Thread.currentThread().name}")
}
}
}
The log "+++ child.await() caught exception java.lang.Exception: test exception with await() in aync, main" . shows the exception is caught, but it still crashes the app.
Why the expiation caught is still crashing the app with coroutines?

As per the documentation of coroutineScope:
This function is designed for parallel decomposition of work. When any child coroutine in this scope fails, this scope fails and all the rest of the children are cancelled (for a different behavior see supervisorScope). This function returns as soon as the given block and all its children coroutines are completed.
Remove the coroutineScope and it should function as you are expecting it should.

find this is helpful as well, and here:
whenever a coroutine created by async() throws an exception,
the same exception is thrown both by its Deferred.await()
and inside the body of the parent coroutine as well!
This means that, no matter if we catch the exception by surrounding await() with try/catch,
our app is still going to crash because the exception is not thrown just
from the await() suspension point

Exception thrown by the child coroutine bubbles up to its immediate parent. You must try catching exceptions in parent coroutines. This way application won't crash.

Related

C++Winrt how to throw and handle exception without terminating program

I have following code
IAsyncOperation<bool> trythiswork()
{
bool contentFound{ false };
try
{
auto result = co_await someAsyncFunc();
winrt::check_bool(result)
if (result)
{
contentFound = true;
}
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
}
co_return contentFound;
}
When the result is false, it fails and throws but catch goes to fail fast and program terminates. How does log function terminate the program? Isn't it supposed to only log the exception? I assumed that I am handling this exception so program won't crash but it is crashing.
So how to throw and catch so that program does not terminate? I do want to throw. And also catch and preferably log the exception as well.
Thanks
The issue can be reproduced using the following code:
IAsyncOperation<bool> someAsyncFunc() { co_return false; }
IAsyncOperation<bool> trythiswork()
{
auto contentFound { false };
try
{
auto result = co_await someAsyncFunc();
winrt::check_bool(result);
// throw std::bad_alloc {};
contentFound = true;
}
catch (...)
{
LOG_CAUGHT_EXCEPTION();
}
co_return contentFound;
}
int main()
{
init_apartment();
auto result = trythiswork().get();
}
As it turns out, everything works as advertised, even if not as intended. When running the code with a debugger attached you will see the following debug output:
The exception %s (0x [trythiswork]
Not very helpful, but it shows that logging itself works. This is followed up by something like
FailFast(1) tid(b230) 8007023E {Application Error}
causing the process to terminate. The WIL only recognizes exceptions of type std::exception, wil::ResultException, and Platform::Exception^. When it handles an unrecognized exception type it will terminate the process by default. This can be verified by commenting out the call to check_bool and instead throwing a standard exception (such as std::bad_alloc). This produces a program that will log exception details, but continue to execute.
The behavior can be customized by registering a callback for custom exception types, giving clients control over translating between custom exception types and HRESULT values. This is useful in cases where WIL needs to interoperate with external library code that uses its own exception types.
For C++/WinRT exception types (based on hresult_error) the WIL already provides error handling helpers that can be enabled (see Integrating with C++/WinRT). To opt into this all you need to do is to #include <wil/cppwinrt.h> before any C++/WinRT headers. When using precompiled headers that's where the #include directive should go.
With that change, the program now works as desired: It logs exception information for exceptions that originate from C++/WinRT, and continues to execute after the exception has been handled.

What will happen if exception thrown of a particular type don't have a catch block corresponding to that exception in c++

For the code given below. How will the code behave and why?
// code goes here..
try {
if(a==0) throw "a is 0";
}
catch(int a) { ; }
a = 19;
//code goes here.....
Since you are throwing a string (aka const char*) but you are only catching values of type int, the exception will not be caught and will go on unwinding the function stack until it finds a try-block willing to catch your exception or it reaches main and aborts your program.
That is, if your catch block does not catch the thrown exception type it is as if it was not there.

Handling wrapped exception in Camel

class MyRouteBuilder extends SpringRouteBuilder {
public void configure() throws Exception {
//initialize camel context here
onException(ChildException.class)
.process(new ChildExceptionHandler())
.handled(true)
.to(errorURI);
onException(ParentException.class)
.process(new ParentExceptionHandler())
.handled(true)
.to(errorURI);
from(startURI)
.processRef("someBeanID")
//other processing here
}
}
Now my "someBeanID" throws ChildException while processing, but ParentExceptionHandler is being invoked for that. Code snippet in "someBeanID" is as below
try {
//some processing
throws new ParentException();
} catch (ParentException e) {
throw new ChildException(e); //being handled by ParentExceptionHandler (why?? should be ChildExceptionHandler??)
throw new ChildException(); //being handled by ChildExceptionHandler (should be)
}
It seems that whenever we wrap any exception, Camel automatically finds the actual wrapped exception and invokes handler for that, instead of invoking handler for wrapper exception. Why is this? Is there any problem in my code ??
Thanks,
Finally resolved....Refer to this
When trapping multiple exceptions, the order of the onException clauses is significant. Apache Camel initially attempts to match the thrown exception against the first clause. If the first clause fails to match, the next onException clause is tried, and so on until a match is found. Each matching attempt is governed by the following algorithm:
If the thrown exception is a chained exception (that is, where an exception has been caught and rethrown as a different exception), the most nested exception type serves initially as the basis for matching. This exception is tested as follows:
If the exception-to-test has exactly the type specified in the onException clause (tested using instanceof), a match is triggered.
If the exception-to-test is a sub-type of the type specified in the onException clause, a match is triggered.
If the most nested exception fails to yield a match, the next exception in the chain (the wrapping exception) is tested instead. The testing continues up the chain until either a match is triggered or the chain is exhausted.

Grails UnexpectedRollbackException occurred: Not Sure Why

I have the following code:
class ServiceA {
def save(Object object) {
if (somethingBadComesBack) {
throw new CustomRuntimeException(data)
}
}
}
class ServiceB {
def serviceA
def save(Object object) {
try {
serviceA.save(object)
// do more stuff if good to go
} catch(CustomRuntimeException e) {
// populate some objects with errors based on exception
}
}
}
class ServiceC {
def serviceB
def process(Object object) {
serviceB.save(object)
if (object.hasErrors() {
// do some stuff
}else{
// do some stuff
}
def info = someMethod(object)
return info
}
}
class SomeController {
def serviceC
def process() {
def object = .....
serviceC.save(object) // UnexpectedRollbackException is thrown here
}
}
When ServiceA.save() is called and an exception occurs, ServiceC.save() is throwing an UnexpectedRollbackException when it tries to return.
I did the following:
try {
serviceC.process(object)
}catch(UnexpectedRollbackException e) {
println e.getMostSpecificCause()
}
and I am getting:
org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
I'm not sure where to start looking for how to fix this.
You're using a runtime exception to roll back the transaction, but that's cheating - it's taking advantage of a side effect. Runtime exceptions roll back transactions automatically since you don't need to catch them so it's assumed that if one is thrown, it wasn't expected and the default behavior is to roll back. You can configure methods to not roll back for specific expected runtime exceptions, but this is somewhat rare. Checked exceptions don't roll back exceptions because in Java they must be caught or declared in the throws, so you have to have either explicitly thrown it or ducked it; either way you had a chance to try again.
The correct way to intentionally roll back a transaction is to call setRollbackOnly() on the current TransactionStatus but this isn't directly accessible in a service method (it is in a withTransaction block since it's the argument to the closure). But it's easy to get to: import org.springframework.transaction.interceptor.TransactionAspectSupport and call TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(). This will required that you rework your code since there won't be an exception to catch, so you'll need to check that it was rolled back with TransactionAspectSupport.currentTransactionStatus().isRollbackOnly().
I'm not sure if it's a Grails issue or standard behavior, but when I was debugging this there were 3 commit calls with 3 different TransactionStatus instances. Only the first had the rollback flag set, but the second was aware of the first and was ok. The third one was considered a new transaction and was the one that triggered the same exception that you were seeing. So to work around this I added this to the 2nd and 3rd service methods:
def status = TransactionAspectSupport.currentTransactionStatus()
if (!status.isRollbackOnly()) status.setRollbackOnly()
to chain the rollback flag. That worked and I didn't get the UnexpectedRollbackException.
It might be easier to combine this with a checked exception. It's still overly expensive since it will fill in the stacktrace unnecessarily, but if you call setRollbackOnly() and throw a checked exception, you will be able to use the same general workflow you have now.
It seems like the default transactionality of services is biting you, and the unchecked exception thrown in Service A is dooming the transaction to rollback only, even once caught.
The above docs say the txn propagation level is PROPAGATION_REQUIRED, which should mean the same transaction is shared from your service C on up to A, if my memory serves me. Can you have Service A's save method throw a checked exception instead of RuntimeException, to avoid the auto-rollback from the latter? Or disable transactions on your services, if that's an option for you?

How can I wait on tasks without throwing TaskCanceledExceptions?

I have a method that creates some Tasks, and then waits on them with WaitAll before returning. The problem is, if those tasks got canceled, then WaitAll throws an AggregateException containing lots of TaskCanceledExceptions.
That means that WaitAll will throw exceptions in two different circumstances:
Exceptions that indicate a genuine error. These mean that there was a condition we didn't know how to handle; they need to propagate as unhandled exceptions, until they eventually terminate the process.
Exceptions that indicate that the user clicked a Cancel button. These mean that the task was canceled and cleaned up, and the program should continue running normally.
The latter fits squarely into the definition of a vexing exception: it's an exception thrown in a completely non-exceptional circumstance, so I have to catch it in order to resume normal control flow. Fortunately it's easy to catch, right? Just add catch (AggregateException) and -- oh wait, that's the same type that gets thrown when there's a fatal error.
I do need to wait for the tasks to finish running before I return (I need to know that they're no longer using their database connections, file handles, or anything else), so I do need the WaitAll or something similar. And if any of the tasks faulted, I do want those exceptions to propagate as unhandled exceptions. I just don't want exceptions for cancel.
How can I prevent WaitAll from throwing exceptions for canceled tasks?
The AggregateException provides a Handle method that can be used for these situations. If for example you want to ignore TaskCanceledException you can do:
var all = new AggregateException(
new NullReferenceException(),
new TaskCanceledException(),
new TaskCanceledException(),
new InvalidOperationException(),
new TaskCanceledException());
try
{
throw all;
}
catch (AggregateException errors)
{
errors.Handle(e => e is TaskCanceledException);
}
If all the exceptions are of type TaskCanceledException, the Handle method will not throw any exception; otherwise a new AggregateException containing only the unhandled exceptions will be thrown.
Based on João Angelo's suggestion, here goes a Task class extension
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MySharedLibrary.Extensions
{
public static class TaskExtensions
{
// This code is based João Angelo's stackoverflow suggestion https://stackoverflow.com/a/8681687/378115
// Use this when a CancellationTokenSource is used
public static void SafeWait(this Task TargetTask, CancellationTokenSource TargetTaskCancellationTokenSource)
{
if (TargetTaskCancellationTokenSource.IsCancellationRequested == false)
{
TargetTaskCancellationTokenSource.Cancel();
}
SafeWait(TargetTask);
}
// Use this when no CancellationTokenSource is used
public static void SafeWait(this Task TargetTask)
{
try
{
if (TargetTask.IsCanceled == false)
{
TargetTask.Wait();
}
}
catch (AggregateException errors)
{
errors.Handle(e => e is TaskCanceledException);
}
}
}
}