
Hello friends!
Welcome to this week’s Sloth Bytes.
I hope you had an amazing week.😁

🦥 No selling out today
I am genuinely considering selling feet pics, so if you work at a company with a marketing budget please forward this to your boss immediately or the feet come out.

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 traceback is actually very helpful to a developer: it tells you the exception type, call stack, file, and line where parsing failed. The problem is that raw tracebacks are not appropriate as a normal user-facing error message, and production systems usually need structured logs/context around them.
Improving with Exception Handling
Let’s handle the errors at a useful boundary: add context for the operator, preserve the original exception, and let the caller decide whether a missing/invalid configuration is recoverable.
import json
class ConfigError(RuntimeError):
pass
def read_config(file_path):
try:
with open(file_path, "r", encoding="utf-8") as file:
return json.load(file)
except FileNotFoundError as exc:
raise ConfigError(f"Configuration file not found: {file_path}") from exc
except PermissionError as exc:
raise ConfigError(f"Cannot read configuration file: {file_path}") from exc
except json.JSONDecodeError as exc:
raise ConfigError(
f"Invalid JSON in {file_path} at line {exc.lineno}, column {exc.colno}"
) from exc
try:
config = read_config("config.json")
except ConfigError as exc:
# At an application boundary, decide whether to exit, use an explicitly
# safe fallback, or report the failure to an operator.
print(f"Startup failed: {exc}")
raise
print(f"Configuration loaded: {config}")What's Happening Here:
Catch specific failures: missing files, permissions, and invalid JSON mean different things.
Add context without destroying the cause:
raise ... from exckeeps the original exception chain for debugging.Handle errors at the right boundary: a low-level parser should not silently decide that an empty/default configuration is safe for the entire application.
Fail fast when required configuration is invalid: quietly continuing with defaults can be more dangerous than crashing, especially for credentials, database addresses, permissions, or production settings.
A developer/operator can now get a concise message and retain the original traceback/cause:
ConfigError: Invalid JSON in config.json at line 1, column 1
The chained exception still contains the original JSONDecodeError and traceback.Why Is Error Handling Important?
Better recovery: expected failures can be handled intentionally instead of crashing at an arbitrary layer.
Better user experience: users can receive a safe, useful message instead of an internal stack trace.
Better debugging: logs should preserve exception type, stack trace, request/job IDs, and useful context so developers can reconstruct what happened.
Security: public errors should not leak secrets, SQL, filesystem paths, tokens, or other internals—but do not “solve” that by deleting the diagnostic information from your private logs.
Other Ways to Handle Errors
1. Logging Errors
Instead of printing errors to the console, log them for later analysis.
import logging
logger = logging.getLogger(__name__)
try:
do_risky_work()
except ExpectedRecoverableError:
# We know how to recover from this specific failure.
logger.warning("Recoverable operation failed", exc_info=True)
use_fallback()
except Exception:
# At a top-level job/request boundary, record the traceback.
logger.exception("Unexpected failure while processing request")
raiselogger.exception(...) records the traceback when called inside an exception handler. In production, structured logs plus correlation/request IDs are usually more useful than a file full of print() statements. Also be careful not to log passwords, tokens, session cookies, or sensitive payloads.
2. Using Assertions
Assertions are useful for documenting internal invariants while developing, but they are not input validation or a production error-recovery mechanism.
# using_assertions.py
def set_age(age):
assert age >= 0, "Age cannot be negative"
# Proceed with setting the age
set_age(-5)In Python specifically, assertions can be disabled with optimization options such as python -O. Never rely on assert to enforce authentication, permissions, financial rules, or validation of untrusted input.
Best Practices for Error Handling
Catch only what you can handle: do not wrap every function in
try/except. Let unexpected failures propagate to a boundary that can log, translate, retry, or terminate correctly.Preserve the cause: when translating exceptions, chain/wrap them so debugging information is not lost.
Separate internal and public errors: developers need detail; users need a safe message and usually an error/reference ID.
Clean up resources: context managers,
finally, RAII/defer-style mechanisms, and transactions help release files, locks, connections, and partial work.Do not swallow failures: empty catch blocks and “log then pretend success” can corrupt state and make incidents harder to diagnose.
Retry selectively: retry transient failures such as some timeouts or rate limits with bounded attempts/backoff. Do not retry deterministic validation errors, and make side-effecting operations idempotent before blindly retrying them.
Document the contract: public APIs/functions should make expected errors and recovery behavior clear.
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.
If you want to keep learning
Debugging techniques — how to reproduce, isolate, and diagnose the bug before deciding how to handle it.
JavaScript debugging beyond console.log() — browser-specific techniques using DevTools, breakpoints, and the debugger statement.
Test doubles explained — use mocks, stubs, and fakes to test failure paths without depending on real services.
Code profiling explained — when your code works but runs painfully slow, profile it instead of guessing.



Thank you to everyone who submitted 😃
vaupunkt, clsmv, JamesHarryT, agentNinjaK, pavan-15-hub, SohamDandekar, ravener, Akoes27, codiling, taypham88, GiantMango, and MustySix66.
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.





