What if your program could catch mistakes before they cause chaos?
Why Handling errors in Go? - Purpose & Use Cases
Imagine you are writing a program that reads a file and processes its content. Without error handling, if the file is missing or unreadable, your program just crashes or behaves unpredictably.
Manually checking every possible failure without a clear system is slow and confusing. You might miss some errors, causing bugs or crashes that are hard to find and fix.
Handling errors lets your program catch problems early and respond gracefully. It helps you keep control, show helpful messages, and avoid crashes.
data := readFile("file.txt") // no check if readFile failed process(data)
data, err := readFile("file.txt") if err != nil { fmt.Println("Error reading file:", err) return } process(data)
It enables your program to be reliable and user-friendly by managing unexpected problems smoothly.
When you upload a photo to a website, error handling ensures the site tells you if the file is too big or corrupted instead of just freezing or crashing.
Errors happen and must be handled to keep programs stable.
Manual checks without structure lead to bugs and confusion.
Error handling provides clear ways to detect and fix problems.
Practice
Solution
Step 1: Understand error type in Go
Errors in Go are values, and when a function returns an error, it returns a value of type error or nil if no error occurred.Step 2: Check error value
To know if an error happened, you check if the error variable is not nil, meaning an error value exists.Final Answer:
By checking if the error variable is not nil -> Option DQuick Check:
error != nil = true means error occurred [OK]
- Checking error == 0 instead of error != nil
- Assuming error is a boolean
- Comparing error to empty string
doTask() in Go?Solution
Step 1: Declare error variable correctly
Use short variable declaration with := to assign the error returned by doTask() to err.Step 2: Check if error is not nil
Use if err != nil to check if an error occurred and handle it inside the block.Final Answer:
err := doTask() if err != nil { // handle error } -> Option BQuick Check:
Use := and err != nil for error handling [OK]
- Using wrong variable declaration syntax
- Checking error against 0 or false
- Using reserved word 'error' as variable name
package main
import (
"errors"
"fmt"
)
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
func main() {
result, err := divide(10, 0)
if err != nil {
fmt.Println(err)
} else {
fmt.Println(result)
}
}Solution
Step 1: Analyze divide function behavior
If b is zero, divide returns 0 and an error with message "division by zero".Step 2: Check main function output
Since divide(10, 0) returns an error, err != nil is true, so fmt.Println(err) prints the error message.Final Answer:
division by zero -> Option AQuick Check:
Error message prints when err != nil [OK]
- Assuming result prints even if error exists
- Ignoring error check and printing zero
- Expecting runtime panic instead of error
package main
import (
"fmt"
"os"
)
func readFile() error {
file, err := os.Open("data.txt")
if err != nil {
return err
}
defer file.Close()
// read file contents
return nil
}
func main() {
err := readFile()
if err != nil {
fmt.Println("File read successfully")
}
}Solution
Step 1: Examine the error handling in main
The main function calls readFile() and prints "File read successfully" if err != nil.Step 2: Identify the logic error
err != nil means an error occurred, so printing success here is incorrect. Success should be printed only if err == nil (no error).Final Answer:
The error check in main should be err == nil, not err != nil -> Option AQuick Check:
Print success only if err == nil [OK]
- Confusing err == nil and err != nil conditions
- Moving defer before error check incorrectly
- Expecting os.Open to never return error
Solution
Step 1: Understand error wrapping in Go
Go 1.13+ supports wrapping errors with fmt.Errorf and %w verb to keep original error context.Step 2: Check each option for correct wrapping
file, err := os.Open("config.json") if err != nil { return fmt.Errorf("failed to open config: %w", err) } return file.Close() uses fmt.Errorf with %w to wrap original error, preserving it. file, err := os.Open("config.json") if err != nil { return errors.New("failed to open config") } return file.Close() creates new error losing original error. file, err := os.Open("config.json") if err != nil { panic(err) } return file.Close() panics instead of returning error. file, err := os.Open("config.json") if err != nil { return err.Error() } return file.Close() returns string instead of error type.Final Answer:
file, err := os.Open("config.json") if err != nil { return fmt.Errorf("failed to open config: %w", err) } return file.Close() -> Option CQuick Check:
Use fmt.Errorf with %w to wrap errors [OK]
- Replacing original error instead of wrapping
- Using panic instead of returning error
- Returning error message string instead of error type
Ready to prove it?
Pass the test and this pattern moves unknown
