# Workflows + Exceptions (Java SDK)

**URL:** <https://community.temporal.io/t/workflows-exceptions-java-sdk/8543>\
**Category:** Community Support\
**Tags:** java-sdk\
**Created:** [June 15, 2023, 5:54pm UTC](https://community.temporal.io/t/workflows-exceptions-java-sdk/8543 "2023-06-15T17:54:07Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![sdonovan](https://avatars.discourse-cdn.com/v4/letter/s/35a633/32.png) [@sdonovan](https://community.temporal.io/u/sdonovan)\
**Post date:** [June 15, 2023, 5:54pm UTC](https://community.temporal.io/t/workflows-exceptions-java-sdk/8543/1 "2023-06-15T17:54:07Z")

</div>

I am almost embarrassed to even ask this question, but something doesn’t seem right.

Temporal 1.20.3, with Java SDK 1.19.1.

Imagine this super simple workflow:

```auto
    @Override
    public void execute() {
        throw new RuntimeException("whoops");
    }

```

When run, I’d expect this workflow to exit, and go into a failed state. That doesn’t happen. Instead, I get weird SDK errors re. replay, and the workflow stays in running state.

Either this is a bug, or I missed a memo somewhere. Any ideas?

Thanks!

Sean

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [June 15, 2023, 10:42pm UTC](https://community.temporal.io/t/workflows-exceptions-java-sdk/8543/2 "2023-06-15T22:42:07Z")

</div>

This is by design. We don’t want workflows to fail on unexpected failures. It allows fixing them without losing workflows. Throw ApplicationFailure to fail the workflow.

---

<div class="post-metadata">

**Author:** ![sdonovan](https://avatars.discourse-cdn.com/v4/letter/s/35a633/32.png) [@sdonovan](https://community.temporal.io/u/sdonovan)\
**Post date:** [June 15, 2023, 11:53pm UTC](https://community.temporal.io/t/workflows-exceptions-java-sdk/8543/3 "2023-06-15T23:53:36Z")

</div>

So I just tried:

`throw ApplicationFailure.newFailure(..)`

. . . and it does the same thing – the workflow doesn’t go into a failed state.

Which gets me thinking. If an activity throws an exception and it’s not caught by the workflow, I’ll wager the workflow correctly goes into a failed state.

I should probably explain a little. Internally, the workflow is coded as a state-machine. If an error occurs, I am trying to figure out the best way to report the error (and/or an error-code). Querying the exception is probably a bad idea, because it means trawling the event-history. Probably saner to write the value(s) as search-attribute(s). In which case, we wouldn’t be throwing an exception, and it would just exit gracefully.

Sean

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [June 16, 2023, 5:10am UTC](https://community.temporal.io/t/workflows-exceptions-java-sdk/8543/4 "2023-06-16T05:10:19Z")

</div>

If you throw this failure from a workflow, it fails.

You probably threw this exception from an activity that by default, retries it. Either add this failure type to the list of `RetryOptions.doNotRetry` or throw `ApplicationFailure.newNonRetryableFailure`.

---

<div class="post-metadata">

**Author:** ![sdonovan](https://avatars.discourse-cdn.com/v4/letter/s/35a633/32.png) [@sdonovan](https://community.temporal.io/u/sdonovan)\
**Post date:** [June 16, 2023, 4:14pm UTC](https://community.temporal.io/t/workflows-exceptions-java-sdk/8543/5 "2023-06-16T16:14:22Z")

</div>

My code is from a workflow:

```auto
@WorkflowInterface
public interface ParentWorkflow {

    @WorkflowMethod(name = "ParentWorkflow")
    void execute();
}

public class ParentWorkflowImpl implements ParentWorkflow {

    @Override
    public void execute() {
        throw newFailure("whoops", null);
    }
}

```

This feels odd to me, this behaviour isn’t normal.

Sean

---

<div class="post-metadata">

**Author:** ![antonio.perez](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/antonio.perez/32/2417_2.png) [@antonio.perez](https://community.temporal.io/u/antonio.perez)\
**Post date:** [June 16, 2023, 5:50pm UTC](https://community.temporal.io/t/workflows-exceptions-java-sdk/8543/6 "2023-06-16T17:50:26Z")

</div>

What is odd @sdonovan?

as Maxim stated, this behavior is by design and allows you to fix the code in case of exceptions like NPE without losing the workflow execution state.

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [June 16, 2023, 6:23pm UTC](https://community.temporal.io/t/workflows-exceptions-java-sdk/8543/7 "2023-06-16T18:23:18Z")

</div>

@sdonovan I cannot reproduce the problem you reported. If an ApplicationFailure is thrown from the child workflow the parent receives it and fails if it is not handled.

Did you specify a child workflow retry policy by any chance?

---

<div class="post-metadata">

**Author:** ![sdonovan](https://avatars.discourse-cdn.com/v4/letter/s/35a633/32.png) [@sdonovan](https://community.temporal.io/u/sdonovan)\
**Post date:** [June 16, 2023, 6:56pm UTC](https://community.temporal.io/t/workflows-exceptions-java-sdk/8543/8 "2023-06-16T18:56:40Z")

</div>

Took me a minute – was just trying a few cases. Problem was mine – passing back the `null` in:

`newFailure("whoops", null)`

. . . . was causing the problem. I hadn’t noticed it.

Short version is:

- From an activity, you can throw either a `RuntimeException` (gets wrapped as an `ApplicationFailure`), or an `ApplicationFailure`. Because it’s always returned as an `ApplicationFailure`, if not caught by the workflow, it’ll cause the workflow to fail.
- However, from a workflow, you can only emit `ApplicationFailure` exceptions, which will cause the workflow to fail. Throwing `RuntimeException` from workflow logic is NOT supported, and won’t cause the workflow to fail.

I think? . . . and, thank you!

S

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [June 16, 2023, 10:40pm UTC](https://community.temporal.io/t/workflows-exceptions-java-sdk/8543/9 "2023-06-16T22:40:51Z")

</div>

You can also configure your workflow to fail on any specific exception type (or on all if you configure Throwable as a type) by setting it in the `WorkflowImplementationOptions.failWorkflowExceptionTypes`.
