When to catch an Exception?
Tags: exceptions, exceptionhandling
Published: 2023-09-10 10:45:43

---
title: When to catch an Exception?
published: true
description: When to catch an Exception and how to handle it?
tags: exceptions,exceptionhandling
# cover_image: https://direct_url_to_image.jpg
# Use a ratio of 100:42 for best results.
# published_at: 2023-09-01 05:17 +0000
---

When developing with a common programming language like Java, C# or likewise, I have faced a dilemma when calling a function/method which may throw exceptions. What should I do about these exceptions? Should I catch them, or let them flow? If I catch them, what should I do with the caught exceptions? Just log them? How much should the `try` block encompass? Only that very function call or the full workflow? So many decisions to make regarding those exceptions! After a bit of soul-searching, I came up with a few rules of mine to handle the exceptions.

Most probably the function/method in question is expected to return some kind of value/object, which will be used for further processing. And an exception means the expected return path was not followed and thus the current workflow cannot continue. Now, if you want to __continue__ despite the exception, you can encompass that one function call to catch the exception and then do one of the following:

__Continue with a default value:__ In this case, the exception was somewhat expected, and you use a default value and continue the workflow.

__Retry:__ This is a common scenario for an operation involving network calls. There can be some issue with the network. So, on a network related exception, you can wait a few milliseconds and try the call again, maybe for some "n" times.

__Try another way:__ It's like one network call fails, then you try to get the value in some other way like proxy or reading from a file.

__Or__ some combination of above three.

And if you do not actually wish to continue the workflow on an exception, it would be better __not__ to encompass only that function-call with try-catch, and then forcefully return/return `null`/assign `null` to the receiving object. Just let the exception flow in its destined error path and keep the "Happy path" of your code clean.

Okay, what about logging? Yes, all the exceptions should be logged/recorded. If possible, an "Application monitoring" service/tool should be used to record the exceptions, so that they can be analyzed later. But to log or record an exception, you have to catch the exception, right? When should you catch for logging/recording?

IMHO, catching the exceptions to record them should happen at the __root__ of a workflow, generically, for all exceptions. This is like catching just before the crash. If your application has well defined workflows, like web applications, the framework or some application monitoring tools may take care of this automatically for you.

Here, by __"workflow"__ I mean a set of operations performed together, which also "fails together". In a web application, handling a request can be considered as a workflow. An application may have one or more parallel or sequential workflows. Failure in one workflow should not affect others. That's why the logging/recording/handling/consumption of the exception should be done at the root of a workflow.

Sometimes, you may want to put some extra information while logging a specific exception, which is not in it. This information can be a message, custom filter, tag etc. Instead of logging it with the specific information, you can catch an exception, put the information within the exception, and then rethrow it. .net has the `Data` property in the Exceptions for this purpose, Java has a `setData` method. When this exception will be caught and recorded at the root of the workflow, the custom information should also be recorded with it.

Another thing to keep in mind is that, when an exception is handled at the root of a workflow, the handling is generic for all exceptions. But when handling and exception in other places, like shown above, it should be specific to certain types of exceptions only. A common way to check if some function is the root of a workflow is to see if some other function depends on it. If not, then this is a root of some workflow.

Hope this helps. Happy coding.