Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine multiple error strings

I am new to golang, my application needs to return multiple errors in a loop, later requires to be combined and returned as a single error string. I am not able to use the string functions to combine the error messages. What methods can be use to combine these errors into a single error before returning ?

package main

import (
   "fmt"
   "strings"
)

func Servreturn() (err error) {

   err1 = fmt.Errorf("Something else occured")
   err2 = fmt.Errorf("Something else occured again")

   // concatenate both the error

   return err3

}
like image 659
Greg Petr Avatar asked Nov 02 '15 04:11

Greg Petr


3 Answers

UPDATE for Go 1.13:

As of Go version 1.13, the language's errors package now supports error wrapping directly.

You can wrap an error by using the %w verb in fmt.Errorf:

err := errors.New("Original error")
err = fmt.Errorf("%w; Second error", err)

Use Unwrap to remove the last error added, and return what remains: previousErrors := errors.Unwrap(err)

Playground Example for errors.Unwrap

Two more functions, errors.Is and errors.As provide ways to check for and retrieve a specific type of error.

Playground Example for errors.As and errors.Is


Dave Cheney's excellent errors package (https://github.com/pkg/errors) include a Wrap function for this purpose:

package main

import "fmt"
import "github.com/pkg/errors"

func main() {
        err := errors.New("error")
        err = errors.Wrap(err, "open failed")
        err = errors.Wrap(err, "read config failed")

        fmt.Println(err) // "read config failed: open failed: error"
}

This also allows additional functionality, such as unpacking the cause of the error:

package main

import "fmt"
import "github.com/pkg/errors"

func main() {
    err := errors.New("original error")
    err = errors.Wrap(err, "now this")

    fmt.Println(errors.Cause(err)) // "original error"
}

As well as the option to output a stack trace when specifying fmt.Printf("%+v\n", err).

You can find additional information about the package on his blog: here and here.

like image 175
Feckmore Avatar answered Oct 15 '22 23:10

Feckmore


String functions don't work on errors because error is really an interface that implements the function Error() string.

You can use string functions on err1.Error() and err2.Error() but not on the "err1" reference itself.

Some errors are structs, like the ones you get from database drivers.

So there's no natural way to use string functions on errors since they may not actually be strings underneath.

As for combining two errors:

Easy, just use fmt.Errorf again.

fmt.Errorf("Combined error: %v %v", err1, err2)

Alternatively:

errors.New(err1.Error() + err2.Error())
like image 39
David Budworth Avatar answered Oct 15 '22 21:10

David Budworth


You could use the strings.Join() and append() function to acheive this slice.

example: golang playgorund

package main

import (
    "fmt"
    "strings"
    "syscall"
)

func main() {

    // create a slice for the errors
    var errstrings []string 

    // first error
    err1 := fmt.Errorf("First error:server error")
    errstrings = append(errstrings, err1.Error())

    // do something 
    err2 := fmt.Errorf("Second error:%s", syscall.ENOPKG.Error())
    errstrings = append(errstrings, err2.Error())

    // do something else
    err3 := fmt.Errorf("Third error:%s", syscall.ENOTCONN.Error())
    errstrings = append(errstrings, err3.Error())

    // combine and print all the error
    fmt.Println(fmt.Errorf(strings.Join(errstrings, "\n")))


}

This would output a single string which you can send back to the client.

First error:server1 
Second error:Package not installed 
Third error:Socket is not connected

hope this helps!

like image 25
askb Avatar answered Oct 15 '22 22:10

askb