CompletableFuture - how do i trigger an exception? - java

This is my code :
public void deletevendor(VendorEntity vendorEntity) throws Exception {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
dwService.deleteVendor(vendorEntity);
} catch (Exception ex) {
log.info("Error occurred ", ex);
}
});
Boolean isCancelled = future.isCancelled();
Boolean isDone = future.isDone();
Boolean isCompletedExceptionally = future.isCompletedExceptionally();
System.out.println("Asynchronous CompletableFuture: " + isCancelled +" "+ isDone+" "+ isCompletedExceptionally );
}
My code inside the try block works fine. I want to trigger the catch block. How can i do that. What could be the inputs that can trigger the exception for my completablefuture?

For sake of experiments with Future this is the way you can trigger the catch clause:
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
try {
throw new Exception("");
} catch (Exception ex) {
log.info("Error occurred ", ex);
}
});
According to your code snippet, as already said, the entire exception throwing logic is inside calling the dwService.deleteVendor(vendorEntity) method. It means you have to pass a specific vendorEntity into this public void deletevendor(VendorEntity vendorEntity) method in order to throw an exception caught in CompletableFuture.

Related

How does Callable return or deal with exceptions?

Im trying to throw an exception in one of the processes under tasks.add (the exception occurs in paymentDao,savePayment() method) , but that exception never shows up in my logs even though I see the thrown exception line being reached in the debugger. I expected the exception to be caught in one of the below catches but it never reaches there. Can someone explain how callable treats an exception that occurs within one of the tasks
private final ExecutorService service = Executors.newFixedThreadPool(100,namedThreadFactory);
List<Callable<Object>> tasks = new ArrayList<>();
try {
if (cacheService.isPayment(
(PaidPending) logProcessor.getCache().asMap().get(fileName), fileName)) {
tasks.add(
() -> {
long startTime = System.currentTimeMillis();
paymentDao.savePayment(paymentR, fileName);
log.info(
"Time taken by savePaymentSummary Key {} : {}",
key,
System.currentTimeMillis() - startTime);
return null;
});
service.invokeAll(tasks);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new CustomException("Failed to insert payment " , e);
} catch (CustomeException e) {
log.error("Error here {}", e);
throw new CustomException("Failed to fetch Payment", e);
}
If a Callable task, c, that you submit to a thread pool throws any Throwable object, th, then th will be stored in the Future object, f, that was returned by the submit(c) call. A subsequent call to f.get() will then throw an ExecutionException, exex, and you can call exex.getCause() to obtain the original Throwable, th.
Your example calls service.invokeAll(tasks), which returns a list of Future objects, but you do not bother to save the list.
Try this:
List<Future<ResultType>> futures = new ArrayList<>();
try {
...
futures = service.invokeAll(tasks);
}
catch (...) {
...
}
...optionally do something else before awaiting results...
for (Future<ResultType> future : futures) {
try {
ResultType result = future.get();
...do something with result...
}
catch (ExecutionException ex) {
Throwable originalException = ex.getCause();
...do something with originalException...
}
}
Note: ResultType is a proxy for whatever your Callable tasks return. I am not sure what type that should be, since in your example, the only value returned is null. Maybe ResultType should just be Object.

How To throw RuntimeExcpetions from CompletableFuture.whenComplete exception block?

I need to re-throw the runtime exception from the CompletableFuture Exception block to the parent method, but looks like the runtimeException is getting logged at the exception block itself and not propagating back to the parent method. Can anyone please advise/suggest me what I am doing wrong here or is this the right way to throw?
I have a function call like below :
void method1(String msg)
{
try
{
method2(msg);
}
catch(RuntimeException e)
{
throw new CustomException("");
}
}
void method2(String msg)
{
CompletableFuture<Void> future = asyncTask.process(msg);
future.whenComplete((res,ex) ->
if(ex != null)
{
log.error("");
throw RuntimeException("abc");
}
else
{ postProcessTasks(msg);
}
);
}
The calling code doesn't wait for the Future to complete or get the status. Here's the core of what needs to be added.
CompletableFuture<Void> future = asyncTask.process(msg)
.thenAccept(this::postProcessTasks);
try {
future.get();
} catch (ExecutionException e) {
Throwable asyncException = e.getCause();
// .. do something here
}
If you intend to propagate an asynchronous Exception back to the caller then whenComplete is probably not the call to use; It is meant to handle exceptions within the asynch call.

throw exception from java task does not work

I am trying to throw an exception inside a task which is run on a separate thread. Then I want to catch the exception on the calling thread. See my trial below:
When I run the code now it hangs at the line with "throws new RuntimeException.."
Task calcTask = createCalcTask();
ExecutorService executor = Executors.newFixedThreadPool(1);
Future future = executor.submit(calcTask);
try {
future.get();
} catch (ExecutionException ex) {
ex.getCause().printStackTrace();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
public Task<Object> createCalcTask() {
return new Task<Object>() {
#Override
protected Object call() throws Exception {
throw new RuntimeException("testE");
}
};
}
try this....
line throwing exception should be inside try block
try {
Future future = executor.submit(calcTask); //
future.get();
} catch (ExecutionException ex) {
ex.printStackTrace();
}

How to throw exception in spark streaming

We have a spark streaming program which pull messages from kafka and process each individual message using forEachPartiton transformation.
If case if there is specific error in the processing function we would like to throw the exception back and halt the program. The same seems to be not happening. Below is the code we are trying to execute.
JavaInputDStream<KafkaDTO> stream = KafkaUtils.createDirectStream( ...);
stream.foreachRDD(new Function<JavaRDD<KafkaDTO>, Void>() {
public Void call(JavaRDD<KafkaDTO> rdd) throws PropertiesLoadException, Exception {
rdd.foreachPartition(new VoidFunction<Iterator<KafkaDTO>>() {
#Override
public void call(Iterator<KafkaDTO> itr) throws PropertiesLoadException, Exception {
while (itr.hasNext()) {
KafkaDTO dto = itr.next();
try{
//process the message here.
} catch (PropertiesLoadException e) {
// throw Exception if property file is not found
throw new PropertiesLoadException(" PropertiesLoadException: "+e.getMessage());
} catch (Exception e) {
throw new Exception(" Exception : "+e.getMessage());
}
}
}
});
}
}
In the above code even if we throw a PropertiesLoadException the program doesn't halt and streaming continues. The max retries we set in Spark configuration is only 4. The streaming program continues even after 4 failures. How should the exception be thrown to stop the program?
I am not sure if this is the best approach but we surrounded the main batch with try and catch and when I get exception I just call close context. In addition you need to make sure that stop gracfully is off (false).
Example code:
try {
process(dataframe);
} catch (Exception e) {
logger.error("Failed on write - will stop spark context immediately!!" + e.getMessage());
closeContext(jssc);
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
throw e;
}
And close function:
private void closeContext(JavaStreamingContext jssc) {
logger.warn("stopping the context");
jssc.stop(false, jssc.sparkContext().getConf().getBoolean("spark.streaming.stopGracefullyOnShutdown", false));
logger.error("Context was stopped");
}
In config :
spark.streaming.stopGracefullyOnShutdown false
I think that with your code it should look like this:
JavaStreamingContext jssc = new JavaStreamingContext(sparkConf, streamBatch);
JavaInputDStream<KafkaDTO> stream = KafkaUtils.createDirectStream( jssc, ...);
stream.foreachRDD(new Function<JavaRDD<KafkaDTO>, Void>() {
public Void call(JavaRDD<KafkaDTO> rdd) throws PropertiesLoadException, Exception {
try {
rdd.foreachPartition(new VoidFunction<Iterator<KafkaDTO>>() {
#Override
public void call(Iterator<KafkaDTO> itr) throws PropertiesLoadException, Exception {
while (itr.hasNext()) {
KafkaDTO dto = itr.next();
try {
//process the message here.
} catch (PropertiesLoadException e) {
// throw Exception if property file is not found
throw new PropertiesLoadException(" PropertiesLoadException: " + e.getMessage());
} catch (Exception e) {
throw new Exception(" Exception : " + e.getMessage());
}
}
}
});
} catch (Exception e){
logger.error("Failed on write - will stop spark context immediately!!" + e.getMessage());
closeContext(jssc);
if (e instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
throw e;
}
}
}
In addition please note that my stream is working on spark 2.1 Standalone (not yarn / mesos) client mode. In addition I implement the stop gracefully my self using ZK.

How to catch the exceptions thrown from CompletableFuture.completeExceptionally() while using CompletableFuture.get()?

How to catch the exceptions thrown from CompletableFuture.completeExceptionally() while using CompletableFuture.get()?
Here is some code
public CompletableFuture<Hello> sayHelloAsync() {
CompletableFuture<Hello> future = new CompletableFuture<>();
try{
sayHello(); //throws HelloException
} catch (HelloException ex) {
future.completeExceptionally(new MyException("hello exception"));
return future;
}
return future;
}
Now I want to do .get() or .join on this as follows
CompletableFuture<Hello> resultFuture = sayHelloAsync();
try{
result.get(); // throws ExecutionException but I want to catch My Exception in the simplest way possible but not by throwing another exception while catching the Execution exception and so on.
} catch(ExecutionException ex) {
throw ex.getCause();
} catch (MyException e) {
e.printStackTrace()
}
This is very ugly. Again I just want to catch MyException in few lines of code as possible and in the cleanest way possible. Not sure if isCompletedExceptionally(), exceptionally, join() can help somehow to catch MyException in the easiest way possible. If so how?

Categories