Exception
An exception is a mechanism used in many programming languages to interrupt the normal flow of execution when an error occurs. In languages like Java and Python, an exception is represented as an object. When an error condition is encountered, an exception is “thrown,” interrupting the current process and propagating up through the program’s call stack to find an appropriate “catch” block to handle the error.
Exceptions can be raised for various reasons, such as attempting to access an unavailable external API, failing to find a specified file, or encountering a division by zero operation. When raised, these exceptions disrupt the normal flow of code execution.
Handling exceptions is typically done using “try-catch” blocks. The code inside the “try” block is executed until an exception is encountered. When that happens, the code inside the corresponding “catch” block is executed to manage the error.
When to Use Error Codes and Exceptions
When to Use Error Codes and Exceptions
HTTP Stack
In the HTTP, status codes serve as a standardized way of communicating the result of a client’s request to a server. These status codes are well-defined, universally understood, and cover a broad range of scenarios from success (
200 OK
) to client errors (404 Not Found
) and server errors (500 Internal Server Error
). Using status codes in HTTP is important for interoperability, as multiple clients and servers across different platforms and languages interact with each other.Within Your Programs
In contrast, within your own program, using exceptions over error codes can be more beneficial for several reasons:
Readability: Using exceptions makes it easier to follow the program’s logic. You can write the main path of execution in a straightforward manner without littering the code with error-checking conditionals.
Maintainability: With exceptions, you separate the error-handling code from the regular code, making it easier to update or extend functionality without risking the introduction of errors.
Rich Context: Exceptions can carry more context about the error, as they can include not just a status but also additional metadata. This can be helpful for debugging or for providing more descriptive error messages.
Stack Unwinding: When an exception is thrown, the runtime system searches back through the call stack to find the nearest enclosing exception handler. This makes it easier to handle errors at the appropriate level of abstraction.
Hybrid Approaches
Some modern languages and frameworks use a combination of both error codes and exceptions for different scenarios. For example, in asynchronous programming or when dealing with third-party libraries, error codes might be more appropriate for indicating status without disrupting the flow of execution.
Summary
While HTTP and similar protocols make effective use of error codes for cross-system communication, within your own programs, using exceptions generally leads to cleaner, more maintainable code. However, the choice between exceptions and error codes can also depend on the programming language, performance considerations, and specific use cases.
Link to original
Checked exceptions are a way of declaring exceptions however you can have exceptions that are unchecked.
Exception good practices
- Provide context to an exception: The only time an exception is going to be read is when something has gone wrong in the program. Therefore write enough context in the exception for the person to quickly identify the cause of the issue.
- Define exception classes in terms of the callers needs: When considering how to define exceptions, via type of error or cause think about what will help the caller the most. This will likely be grouping errors based on how they will handle it.
- Wrap 3rd party libraries and group exceptions: It is a good practice to wrap 3rd party libraries and join up similar exceptions into one internally named exception. This saves people having to remember all the exceptions that can be thrown for a given library.
- Only split exception classes if you want to handle them differently: When deciding if a type of error needs its own class in your code, only choose to split it up if there are cases when you need to handle the two errors differently.
- Handle errors at the lowest possible level: Try to avoid try-catch logic wherever possible. If you need to use an exception for a special cases consider using the Special case pattern.