Declare new error in Golang [SOLVED]


GOLANG Solutions, GO

Author: Tuan Nguyen
Reviewer: Deepak Prasad

In the previous post, we talked about handle errors in Golang. In this tutorial, we will provide some examples of defining errors using New() function:

errors: Package errors implements functions to manipulate errors. The New function creates errors whose only content is a text message.

 

Method-1: Using errors.New to declare new error in GO

Example 1: Simple use of errors.New() function to return a new error

func New(text string) error: New returns an error that formats as the given text. Each call to New returns a distinct error value even if the text is identical.

Here is an example of using errors.New() in Go:

package main

import (
	"errors"
	"fmt"
)

func main() {
	err := errors.New("This is a new error!")
	if err != nil {
		fmt.Print(err)
	}
}

 

Example 2: More complex use of errors.New() to return new error

Here is an example of checking a string begins with 'S' or not. If invalid, return an error:

package main

// import the errors package
import (
  "errors"
  "fmt"
  "strings"
)

// check if string starts with S 
func checkStartWith(str string) error {
  // create a new error
  newError := errors.New("Invalid String")

  if !(strings.HasPrefix(str, "S") || strings.HasPrefix(str, "s")) {
    return newError
  }

  // return nil if there is no error
  return nil
}

func main() {
  str1 := "Hello"
  str2 := "Sorry"

  // call the function
  err1 := checkStartWith(str1)

  // check if the err is nil or not
  if err1 != nil {
    fmt.Println(err1)
  } else {
    fmt.Println("Valid String")
  }

  err2 := checkStartWith(str2)

  // check if the err is nil or not
  if err2 != nil {
    fmt.Println(err2)
  } else {
    fmt.Println("Valid String")
  }

}

Output:

Invalid String
Valid String

 

Method-2: Using Errorf() with fmt package to return an error

func Errorf(format string, a ...any) error: Errorf formats according to a format specifier and returns the string as a value that satisfies error. If the format specifier includes a %w verb with an error operand, the returned error will implement an Unwrap method returning the operand.

The example below shown how to use Errorf() function to return an error. We create a map which key is the id, then we check if id 17 is in the map. If not, raise an error:

package main

import (
	"fmt"
)


func main() {
	const name, id = "Daniel", 17
	listId := map[int]string{1: "Anna", 2: "Bob", 5: "Harry", 7: "Chris", 8:"Cody", 18: "Ron"}
	if _, ok := listId[17]; !ok {
		err := fmt.Errorf("user %q (id %d) not found", name, id)
		fmt.Println(err.Error())

	}
}

Output:

user "Daniel" (id 17) not found

 

Method-3: Define a custom error type with interface

You have to satisfy the predeclared error interface in order to define a custom error type:

type error interface {
    Error() string
}

We will write a function to divide 2 positive integers. If one of the input is negative integer, raise an InvalidParam error; if DivisionByZero raise an DivisionByZero error:

package main

import "fmt"

type error interface {
    Error() string
}

type DivisionByZero struct {
  message string
}

type InvalidParam struct {
	message string
}


// define Error() method on the struct
func (e *DivisionByZero) Error() string {
  return "Number Cannot Be Divided by Zero"
}

// define Error() method on the struct
func (e *InvalidParam) Error() string {
	return "Numbers must be positive integers"
  }

func dividePosInt(n1 int, n2 int) (int, error) {
  if (n1<0 || n2< 0) {
	return 0, &InvalidParam{}
  } else if n2 == 0 {
    return 0, &DivisionByZero{}
  }  else {
    return n1 / n2, nil
  }
}

func main() {
  x1 := 20
  x2 := 0
  result, err := dividePosInt(x1, x2)

  // check if error occur or not
  if err != nil {
    fmt.Println(err)
  } else {
    fmt.Printf("Result: %d", result)
  }

  y1 := -2
  y2 := 0
  result2, err := dividePosInt(y1, y2)

  // check if error occur or not
  if err != nil {
    fmt.Println(err)
  } else {
    fmt.Printf("Result: %d", result2)
  }
}

Output:

Number Cannot Be Divided by Zero
Number must be positive integers

 

Summary

A strong piece of code must be capable of handling faults. I have shown you some ways to return an error and then handle it in the caller. You can use errors.New() functions or implement your own interface to handle errors in your program.

 

References

https://go.dev/doc/tutorial/handle-errors
https://pkg.go.dev/errors
https://pkg.go.dev/fmt

 

Tuan Nguyen

Tuan Nguyen

He is proficient in Golang, Python, Java, MongoDB, Selenium, Spring Boot, Kubernetes, Scrapy, API development, Docker, Data Scraping, PrimeFaces, Linux, Data Structures, and Data Mining. With expertise spanning these technologies, he develops robust solutions and implements efficient data processing and management strategies across various projects and platforms. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment