Golang Error Handling Quiz
40 comprehensive questions on Golang error handling, covering error values, custom error types, fmt.Errorf with wrapping, sentinel vs typed errors, and errors.Is & errors.As — with 18 code examples demonstrating error handling patterns.
Question 1
What is the error type in Golang?
Question 2
How do you create a simple error in Golang?
package main
import "errors"
func main() {
err := errors.New("something went wrong")
println(err.Error())
}Question 3
What is the zero value of error?
Question 4
How do you check if an error occurred?
package main
import "fmt"
func doSomething() error {
return nil // or some error
}
func main() {
if err := doSomething(); err != nil {
fmt.Println("Error:", err)
}
}Question 5
What does fmt.Errorf do?
package main
import "fmt"
func main() {
err := fmt.Errorf("failed to process %s: %w", "file.txt", originalErr)
fmt.Println(err)
}Question 6
What is error wrapping?
Question 7
How do you create a custom error type?
package main
import "fmt"
type MyError struct {
Code int
Msg string
}
func (e MyError) Error() string {
return fmt.Sprintf("code %d: %s", e.Code, e.Msg)
}
func main() {
err := MyError{404, "not found"}
fmt.Println(err.Error())
}Question 8
What is a sentinel error?
Question 9
What is the difference between sentinel and typed errors?
Question 10
What does errors.Is do?
package main
import (
"errors"
"fmt"
)
var ErrNotFound = errors.New("not found")
func main() {
err := fmt.Errorf("failed: %w", ErrNotFound)
fmt.Println(errors.Is(err, ErrNotFound)) // true
}Question 11
What does errors.As do?
package main
import (
"errors"
"fmt"
)
type MyError struct {
Code int
}
func (e MyError) Error() string { return "error" }
func main() {
var myErr MyError
err := fmt.Errorf("wrapped: %w", MyError{Code: 404})
if errors.As(err, &myErr) {
fmt.Println(myErr.Code) // 404
}
}Question 12
In a web API, you're handling different types of validation errors. Should you use sentinel errors or typed errors for field validation failures?
Question 13
What happens when you wrap an error multiple times?
package main
import "fmt"
func main() {
original := errors.New("original")
wrapped1 := fmt.Errorf("level1: %w", original)
wrapped2 := fmt.Errorf("level2: %w", wrapped1)
fmt.Println(wrapped2)
}Question 14
Why should you avoid comparing errors with == ?
package main
import "errors"
var ErrNotFound = errors.New("not found")
func main() {
err := fmt.Errorf("wrapped: %w", ErrNotFound)
// err == ErrNotFound is false!
}Question 15
How do you implement a custom error type with additional data?
package main
import "fmt"
type ValidationError struct {
Field string
Value string
Rule string
}
func (e ValidationError) Error() string {
return fmt.Sprintf("validation failed for %s='%s': %s", e.Field, e.Value, e.Rule)
}
func main() {
err := ValidationError{Field: "email", Value: "invalid", Rule: "format"}
fmt.Println(err)
}Question 16
What is the benefit of error wrapping?
Question 17
How do you handle errors that should not be wrapped?
package main
import "fmt"
func main() {
err := someOperation()
if err != nil {
return fmt.Errorf("operation failed: %s", err.Error()) // No %w
}
}Question 18
What is the errors package used for?
Question 19
In a database layer, you're implementing connection errors. Should you use a sentinel error or a typed error for connection failures?
Question 20
What does this errors.As example demonstrate?
package main
import (
"errors"
"fmt"
)
type TimeoutError struct {
Duration time.Duration
}
func (e TimeoutError) Error() string { return "timeout" }
func main() {
err := fmt.Errorf("operation failed: %w", TimeoutError{5 * time.Second})
var timeout TimeoutError
if errors.As(err, &timeout) {
fmt.Println("Timeout after:", timeout.Duration)
}
}Question 21
Why is error handling explicit in Golang?
Question 22
What is the problem with this error handling?
package main
import "log"
func riskyOperation() error {
return errors.New("failed")
}
func main() {
err := riskyOperation()
log.Fatal(err) // Always exits
}Question 23
How do you create an error that implements multiple interfaces?
package main
import "fmt"
type MyError struct {
msg string
}
func (e MyError) Error() string { return e.msg }
func (e MyError) Timeout() bool { return true }
func main() {
var err error = MyError{"timeout"}
fmt.Println(err.Error())
}Question 24
What is the difference between %v and %w in fmt.Errorf?
package main
import "fmt"
func main() {
original := errors.New("original")
err1 := fmt.Errorf("wrapped: %v", original) // string
err2 := fmt.Errorf("wrapped: %w", original) // wrapped
}Question 25
In a REST API, you're returning errors to clients. How should you structure error responses?
Question 26
What happens when errors.As doesn't find the target type?
package main
import "errors"
func main() {
err := errors.New("simple error")
var myErr MyError
found := errors.As(err, &myErr)
fmt.Println(found) // false
}Question 27
Why should you wrap errors at API boundaries?
Question 28
What is the problem with string-based error checking?
package main
func main() {
err := errors.New("file not found")
if err.Error() == "file not found" { // Bad!
// handle
}
}Question 29
How do you implement a temporary error for retry logic?
package main
import "fmt"
type TempError struct {
msg string
}
func (e TempError) Error() string { return e.msg }
func (e TempError) Temporary() bool { return true }
func main() {
var err error = TempError{"temporary failure"}
// Can check if error is temporary
}Question 30
What is the Go proverb about errors?
Question 31
In a microservices architecture, how should you handle errors from downstream services?
Question 32
What does this error inspection demonstrate?
package main
import (
"errors"
"fmt"
)
var ErrNotFound = errors.New("not found")
var ErrPermission = errors.New("permission denied")
func main() {
err := fmt.Errorf("db error: %w", ErrNotFound)
if errors.Is(err, ErrNotFound) {
fmt.Println("Handle not found")
} else if errors.Is(err, ErrPermission) {
fmt.Println("Handle permission")
}
}Question 33
Why should you avoid creating error types for every error case?
Question 34
What is the output of this wrapped error inspection?
package main
import (
"errors"
"fmt"
)
type MyError struct {
Code int
}
func (e MyError) Error() string { return "my error" }
func main() {
original := MyError{Code: 404}
wrapped := fmt.Errorf("wrapped: %w", original)
var target MyError
if errors.As(wrapped, &target) {
fmt.Println(target.Code) // 404
}
}Question 35
What is the most important principle of error handling in Golang?
Question 36
How do you handle errors in defer statements?
package main
import "fmt"
func process() (err error) {
f, err := os.Open("file.txt")
if err != nil {
return err
}
defer func() {
if closeErr := f.Close(); closeErr != nil {
if err == nil {
err = closeErr
} else {
// handle both errors
}
}
}()
return nil
}Question 37
What is the difference between error and panic?
Question 38
How do you implement error aggregation?
package main
import "fmt"
type MultiError []error
func (me MultiError) Error() string {
var msgs []string
for _, err := range me {
msgs = append(msgs, err.Error())
}
return fmt.Sprintf("multiple errors: %v", msgs)
}
func main() {
errs := MultiError{errors.New("err1"), errors.New("err2")}
fmt.Println(errs)
}Question 39
Why should you avoid using errors in performance-critical code?
Question 40
What is the key insight about Golang's error handling philosophy?
