šŸ¦„Error Handling For Dummies

Sponsored by

Hello friends!

Welcome to this weekā€™s Sloth Bytes.

I hope you had an amazing week.šŸ˜ 

Unlock Windsurf Editor, by Codeium.

Introducing the Windsurf Editor, the first agentic IDE. All the features you know and love from Codeiumā€™s extensions plus new capabilities such as Cascade that act as collaborative AI agents, combining the best of copilot and agent systems. This flow state of working with AI creates a step-change in AI capability that results in truly magical moments.

Sloths only come down from trees to use the bathroom

Sloths donā€™t like to come down to the ground, and will only do so for one reason ā€“ to go to the bathroom. In the wild, they do this approximately once every 5 days, although in captivity they often do it more often.

Have you ever used an application that suddenly crashed without warning, leaving you confused and frustrated?

With error handling we can reduce that.

In this newsletter, weā€™ll dive a bit deeper about error handling, discuss why it's so important, and look at alternative methods for handling errors.

Iā€™ve already talked about methods for debugging in an earlier issue if youā€™re interested.

A Confusing Error Example

Let's consider a situation where an application reads data from a configuration file.

Suppose we have the following Python code that reads a JSON file:

# config_reader.py
import json

def read_config(file_path):
    with open(file_path, 'r') as file:
        config = json.load(file)
    return config

config = read_config('config.json')
print(f"Configuration loaded: {config}")

If the config.json file contains invalid JSON, the program will crash with an error like:

#Fake error btw
Traceback (most recent call last):
  File "config_reader.py", line 9, in <module>
    config = read_config('config.json')
  File "config_reader.py", line 6, in read_config
    config = json.load(file)
  File "/fake_usr/lib/python3.8/json/__init__.py", line 293, in load
    return loads(fp.read())
...
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

This error message is not that helpful.

Improving with Exception Handling

Let's enhance the code with proper exception handling to make the error clearer and handle different error scenarios.

# config_reader_safe.py
import json

def read_config(file_path):
    try:
        with open(file_path, 'r') as file:
            try:
                config = json.load(file)
            except json.JSONDecodeError as e:
                print(f"Error: Failed to parse JSON in '{file_path}'.")
                print("Check if the file contains valid JSON.")
                print(f"Details: {e}")
                return None
    except FileNotFoundError:
        print(f"Error: Configuration file '{file_path}' not found.")
        return None
    except PermissionError:
        print(f"Error: Insufficient permissions to read '{file_path}'.")
        return None
    return config

config = read_config('config.json')
if config:
    print(f"Configuration loaded: {config}")
else:
    print("Using default configuration.")

What's Happening Here:

  • FileNotFoundError Handling: If the file doesn't exist, we inform the user.

  • JSONDecodeError Handling: If the JSON is invalid, we provide a clear message.

  • PermissionError Handling: If the file can't be read due to permissions, we notify the user.

  • Graceful Degradation: If loading fails, we proceed with a default configuration instead of crashing.

Even if an error does happen itā€™s easier to understand:

Error: Failed to parse JSON in 'config.json'.
Check if the file contains valid JSON.
Details: Expecting value: line 1 column 1 (char 0)

Why Is Error Handling Important?

  1. Enhanced User Experience:

    Users receive clear, understandable messages instead of cryptic error traces, reducing frustration.

  2. Increased Reliability:

    The application can handle unexpected situations without crashing, improving stability.

  3. Simplified Debugging:

    Developers get precise information about what went wrong, making it easier to fix issues.

  4. Security Considerations:

    Proper error handling can prevent leaking sensitive information through unhandled exceptions.

Other Ways to Handle Errors

1. Logging Errors

Instead of printing errors to the console, log them for later analysis.

# error_logging.py
import logging

logging.basicConfig(filename='app.log', level=logging.ERROR)

try:
    # Code that may raise an exception
    ...
except Exception as e:
    logging.error(f"An error occurred: {e}")
    print("An unexpected error occurred. Please try again later.")

Logging is especially useful in production environments where you don't want to expose internal errors to users.

2. Using Assertions

Assertions can catch programming errors during development.

# using_assertions.py
def set_age(age):
    assert age >= 0, "Age cannot be negative"
    # Proceed with setting the age

set_age(-5)

Note that assertions should not be used for handling runtime errors from user input; they are mainly for debugging purposes.

Best Practices for Error Handling

  1. Handle Exceptions Appropriately:

    Only catch exceptions you can handle meaningfully. Let others propagate up to higher levels. This means you donā€™t have to write exceptions for every possible situation if you donā€™t need to.

  2. Provide Meaningful Messages:

    Error messages should be clear but not expose sensitive information.

  3. Use Finally Blocks or Context Managers:

    Ensure that resources are cleaned up properly, even if an error occurs.

  4. Avoid Suppressing Exceptions:

    Don't use empty catch blocks or overly broad exception handlers that hide errors.

  5. Document Error Handling Behavior:

    Make it clear how your functions handle errors, especially in public APIs

Error handling is an integral part of software development that enhances the robustness, reliability, and user experience of your applications.

By understanding different error handling techniques and how they are implemented across various programming languages, you can write code that not only works but is also maintainable and professional.

Remember, errors are inevitable, but how you handle them makes all the difference.

Thank you to everyone who submitted šŸ˜ƒ 

12 vs 24 Hours

Create a function that converts 12-hour time to 24-hour time or vice versa. Return the output as a string.

Examples

convertTime("12:00 am")
output = "0:00"

convertTime("6:20 pm")
output = "18:20"

convertTime("21:00")
output = "9:00 pm"

convertTime("5:05")
output ="5:05 am"

Notes

  • A 12-hour time input will be denoted with an am or pm suffix.

  • A 24-hour input time contains no suffix.

How To Submit Answers

Reply with

  • A link to your solution (github, twitter, personal blog, portfolio, replit, etc)

  • or if youā€™re on the web version leave a comment!

Google vid out if you didnā€™t noticeā€¦

Check it out here and feel free to make fun of my code for it.

Thatā€™s all from me!

Have a great week, be safe, make good choices, and have fun coding.

If I made a mistake or you have any questions, feel free to comment below or reply to the email!

See you all next week.

Reply

or to participate.