How to handle cancel child workflow?

Hi,

I was wondering how to properly handle nested cancel workflows. For example, I have the following code:

   try {
      Promise<Void> childWorkflows [] = .....
      Promise.allOf(childWorkflows).get();
   }  catch( WorkflowExecutionFailedException ex) {
      // ? 
  }

When a childworkflow is canceled, I believe a WorkflowExecutionFailedException is thrown. What is the proper way to handle it by understanding that it was caused by a cancel?

The bottom is what gets printed in the temporal UI for the failure reason for the WorkflowExecutionFailed. In code wise, its not clear how you identify its a cancel reason.

java.base/java.lang.Thread.getStackTrace(Thread.java:1602)
io.temporal.internal.sync.CompletablePromiseImpl.throwFailure(CompletablePromiseImpl.java:136)
io.temporal.internal.sync.CompletablePromiseImpl.getImpl(CompletablePromiseImpl.java:95)
io.temporal.internal.sync.CompletablePromiseImpl.get(CompletablePromiseImpl.java:74)
io.temporal.internal.sync.AllOfPromise.get(AllOfPromise.java:81)
io.temporal.internal.sync.AllOfPromise.get(AllOfPromise.java:29)
...<removed lines>
jdk.internal.reflect.GeneratedMethodAccessor492.invoke(Unknown Source)
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.base/java.lang.reflect.Method.invoke(Method.java:566)
io.temporal.internal.sync.POJOWorkflowImplementationFactory$POJOWorkflowImplementation$RootWorkflowInboundCallsInterceptor.execute(POJOWorkflowImplementationFactory.java:324)
io.temporal.internal.sync.POJOWorkflowImplementationFactory$POJOWorkflowImplementation.execute(POJOWorkflowImplementationFactory.java:282)
io.temporal.internal.sync.WorkflowExecuteRunnable.run(WorkflowExecuteRunnable.java:53)
io.temporal.internal.sync.SyncWorkflow.lambda$start$0(SyncWorkflow.java:126)
io.temporal.internal.sync.CancellationScopeImpl.run(CancellationScopeImpl.java:101)
io.temporal.internal.sync.WorkflowThreadImpl$RunnableWrapper.run(WorkflowThreadImpl.java:107)
java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
java.base/java.lang.Thread.run(Thread.java:829)

Caused By: Child canceled 
io.temporal.internal.statemachines.ChildWorkflowStateMachine.notifyCanceled(ChildWorkflowStateMachine.java:290)
io.temporal.internal.statemachines.FixedTransitionAction.apply(FixedTransitionAction.java:45)
io.temporal.internal.statemachines.StateMachine.executeTransition(StateMachine.java:137)
io.temporal.internal.statemachines.StateMachine.handleHistoryEvent(StateMachine.java:91)
io.temporal.internal.statemachines.EntityStateMachineBase.handleEvent(EntityStateMachineBase.java:63)
io.temporal.internal.statemachines.WorkflowStateMachines.handleEventImpl(WorkflowStateMachines.java:210)
io.temporal.internal.statemachines.WorkflowStateMachines.handleEvent(WorkflowStateMachines.java:178)
io.temporal.internal.replay.ReplayWorkflowRunTaskHandler.handleEvent(ReplayWorkflowRunTaskHandler.java:140)
io.temporal.internal.replay.ReplayWorkflowRunTaskHandler.handleWorkflowTaskImpl(ReplayWorkflowRunTaskHandler.java:180)
io.temporal.internal.replay.ReplayWorkflowRunTaskHandler.handleWorkflowTask(ReplayWorkflowRunTaskHandler.java:150)
io.temporal.internal.replay.ReplayWorkflowTaskHandler.handleWorkflowTaskWithEmbeddedQuery(ReplayWorkflowTaskHandler.java:201)
io.temporal.internal.replay.ReplayWorkflowTaskHandler.handleWorkflowTask(ReplayWorkflowTaskHandler.java:114)
io.temporal.internal.worker.WorkflowWorker$TaskHandlerImpl.handle(WorkflowWorker.java:319)
io.temporal.internal.worker.WorkflowWorker$TaskHandlerImpl.handle(WorkflowWorker.java:279)
io.temporal.internal.worker.PollTaskExecutor.lambda$process$0(PollTaskExecutor.java:73)
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
java.base/java.lang.Thread.run(Thread.java:829)

Look at the ex.getCause()