CodeBlanks Logo Icon CodeBlanks

Returning errors

Learn to return errors with errors.New and fmt.Errorf.

Returning errors

Use errors.New for simple errors and fmt.Errorf for formatted messages and context. Errors the caller can compare against are defined as package-level variables (sentinel errors):

var ErrBulunamadi = errors.New("kayıt bulunamadı")

func bul(id int) (string, error) {
    if id != 1 {
        return "", fmt.Errorf("kullanıcı %d: %w", id, ErrBulunamadi)
    }
    return "Ada", nil
}

Error messages start with a lower-case letter and don't end with a period, because they are used by appending to other messages.

Adding context to errors

As an error is passed upward, each layer adds what it was doing; the result is a readable chain:

// repository: kayıt bulunamadı
// service:    kullanıcı 7: kayıt bulunamadı
// handler:    profil yüklenemedi: kullanıcı 7: kayıt bulunamadı

Both logging and returning the same error leads to duplicate log lines; either handle it or add context and pass it on.

Practice Find a user

Write ErrBulunamadi and the bul(id int) (string, error) function above. Print the results of bul(1) and bul(7) on separate lines (fmt.Println(bul(...))).

Starter code

main.go
package main

import (
    "errors"
    "fmt"
)

func main() {
    // buraya yaz
}

Sample solution

main.go
package main

import (
    "errors"
    "fmt"
)

var ErrBulunamadi = errors.New("kayıt bulunamadı")

func bul(id int) (string, error) {
    if id != 1 {
        return "", fmt.Errorf("kullanıcı %d: %w", id, ErrBulunamadi)
    }
    return "Ada", nil
}

func main() {
    fmt.Println(bul(1))
    fmt.Println(bul(7))
}

Expected output

Ada <nil>
 kullanıcı 7: kayıt bulunamadı

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 When there is an error, what should the other return values be?

  • Anything
  • Their zero values ("", 0, nil) Correct answer
  • The last valid value
  • -1

Explanation: Convention: when there is an error the other values aren't trusted and zero values are returned; the caller checks the error first.

2 Wrap with context

Question
return "", fmt.Errorf("kullanıcı %d: ____", id, ErrBulunamadi)
Answer
return "", fmt.Errorf("kullanıcı %d: %w", id, ErrBulunamadi)

Explanation: %w wraps the error; the caller can find the original with errors.Is.

3 Tool and use

Term Meaning
errors.New A simple error
fmt.Errorf + %w An error with context
var ErrX = ... A comparable error
return "", err Zero value + error

All lessons in Beginner