Last active
January 31, 2021 00:29
-
-
Save albertywu/2ec1f31171d11d682e4e059bc6c9c3f8 to your computer and use it in GitHub Desktop.
error handling in golang
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "bytes" | |
| "fmt" | |
| "os" | |
| "os/exec" | |
| "strings" | |
| ) | |
| // run quietly, unless there is an error | |
| func main() { | |
| wd, err := os.Getwd() | |
| if err != nil { | |
| fmt.Fprintln(os.Stderr, err) | |
| os.Exit(1) | |
| } | |
| result, err := gitVersion(wd) | |
| if err != nil { | |
| fmt.Fprintln(os.Stderr, err) | |
| os.Exit(1) | |
| } | |
| fmt.Println(result) | |
| result, err = gitLog(wd) | |
| // example of switch type assertion to convert interface value to concrete struct implementation | |
| // can be used to trigger certain behaviors off error subtypes | |
| if ee, ok := err.(*ErrExecution); ok { | |
| fmt.Fprintln(os.Stderr, "found an ErrExecution!", ee.Stderr) | |
| os.Exit(1) | |
| } | |
| if err != nil { | |
| fmt.Println(err) | |
| } | |
| fmt.Println(result) | |
| } | |
| func gitVersion(cwd string) (string, error) { | |
| return execute(cwd, "git", []string{"version"}) | |
| } | |
| func gitLog(cwd string, args ...string) (string, error) { | |
| return execute(cwd, "git", append([]string{"log"}, args...)) | |
| } | |
| type ErrExecution struct { | |
| error | |
| Cmd *exec.Cmd | |
| ExitCode int | |
| Stderr string | |
| } | |
| func (e ErrExecution) Error() string { | |
| joinedArgs := strings.Join(e.Cmd.Args, " ") | |
| return fmt.Sprintf(` | |
| Error: %v | |
| Executable: %s | |
| Command: "%s" | |
| Stderr: %s`, e.error, e.Cmd.Path, joinedArgs, e.Stderr) | |
| } | |
| func execute(cwd string, command string, args []string) (string, error) { | |
| cmd := exec.Command(command, args...) | |
| stdout := bytes.Buffer{} | |
| stderr := bytes.Buffer{} | |
| cmd.Stdout = &stdout | |
| cmd.Stderr = &stderr | |
| cmd.Dir = cwd | |
| err := cmd.Run() | |
| if err != nil { | |
| return "", &ErrExecution{error: err, Cmd: cmd, ExitCode: cmd.ProcessState.ExitCode(), Stderr: stderr.String()} | |
| } | |
| return stdout.String(), nil | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment