How to Handle Errors Gracefully in Our Apps
By: John Au-Yeung
Tags: Programming, Software Engineering, Software Development, Web Development, Technology

Photo by Johann Siemens on Unsplash

Handling errors gracefully in our apps ensure that failure will be noticed quickly so users or developers can fix the issues presented.

In this article, we’ll look at how to handle errors in a graceful way to make fixing them easier.

Crash Early

Our programs should crash early so that we can detect problems as soon as we can.

For instance, instead of letting a program continue to write invalid data to a database, we should check if the data and throw an error before it gets written.

This way, the user can reenter the data correctly and then save it to the database.

Once it’s in the database, then we’ll have to go to the database to fix it, which is a lot harder.

And if lots of people enter invalid data and we let them save them, then it’ll be pretty much impossible to fix quickly and it’ll be a nightmare for everyone.

We can throw exceptions in most languages to throw an error. Then the error will be obvious to us right away.

Assertive Programming

We should use assertions if something that we don’t allow to happen can’t happen.

For instance, if we don’t allow something to be null , then we should check for that before a program or function can continue to run.

This way, we won’t let invalid values propagate in our system.

Leave Assertions Turned On

Assertions don’t add overhead to code. Also, we shouldn’t assume that assertions are only triggered by bugs in the code.

It can also be triggered by user error. Therefore, we should leave them on in any environment.

Therefore, turning them off won’t save us any resources, but it can cause us lots of problems later on.

We shouldn’t have assertions that have side effects. This way, we know what we’re checking is just what we’re checking against.

If we commit side effects while running for assertions, then we may be doing something that we didn’t expect and check for in our side effects and we’ll run into problems even if we check for them.

When to Use Exceptions

Exceptions should be used whenever they’re available. For example, a try...catch block is much cleaner than using if and else to check status codes returned by different functions.

If those functions throw exceptions instead of returning error values, then it makes our code much cleaner if we catch them and then handle them gracefully.

We should use them when an error may arise from the running code. For instance, if a function throws an exception when it checks if a file exists, then we need to catch the error and handle that.

If the file must be there, then we can catch the exception if it’s not there. If it’s optional, then we may just check if the file exists and run some code if it is.

Programs that throw and catch exceptions everywhere suffer from readability and maintainability problems as they jump from one place to another when an exception is thrown.

Also, encapsulation is broken since they’re more tightly coupled by handling exceptions.

Error Handlers Are an Alternative

Instead of throwing and catching exceptions everywhere, we can also write error handler functions to deal with errors gracefully.

We can use them in any language since they’re just regular functions.

They can handle all the errors thrown in one central place. We can just write one error handler and use them everywhere.

Photo by Jacob Mejicanos on Unsplash

Cleaning Up Resources

Our programs should clean up after themselves when needed. For instance, if our program writes temporary files to the file system, then we should clean them up when our program is done.

This also includes situations when our program ends when an error occurs. We got to make sure that resources are freed in those situations.

This way, we won’t have lots of unused temporary files lying around after our program runs multiple times.

However, if a top-level structure of our program is responsible for cleaning up resources, then we should let them do that.

If it doesn’t then our code should do it for them.

Conclusion

Our program should handle errors gracefully and clean up resources after they’re used.

Also, errors should be displayed early so that everyone involved can act of them faster.