aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2020-12-22 19:12:46 +0100
committerTeddy Wing2020-12-22 19:12:46 +0100
commita3fbf30512c30a8c9fac051063954f5a64eff9f3 (patch)
tree0e56773d6e7193b942b55e055adb879615fce2b5
parentb89d9ed327fe7689edd72bfec815d754a724b850 (diff)
downloadbrowserenv-format-errors-and-use-error-values.tar.bz2
Return package-specific error messagesformat-errors-and-use-error-values
Instead of passing errors through to clients, wrap them with a "browserenv" error message to add context. Add new error types that can be matched against.
-rw-r--r--browserenv.go17
-rw-r--r--error.go76
2 files changed, 87 insertions, 6 deletions
diff --git a/browserenv.go b/browserenv.go
index 6812700..eaff96e 100644
--- a/browserenv.go
+++ b/browserenv.go
@@ -50,7 +50,7 @@ func OpenFile(path string) error {
if envCommand != "" {
path, err := filepath.Abs(path)
if err != nil {
- return err
+ return &PathResolutionError{path, err}
}
url := "file://" + path
@@ -70,12 +70,12 @@ func OpenReader(r io.Reader) error {
if envCommand != "" {
tempFile, err := ioutil.TempFile("", "browserenv")
if err != nil {
- return err
+ return &TempFileError{err}
}
_, err = io.Copy(tempFile, r)
if err != nil {
- return err
+ return &CopyError{err}
}
return OpenFile(tempFile.Name())
@@ -110,18 +110,23 @@ func runBrowserCommand(commands, url string) error {
commandList := strings.Split(commands, commandSeparator)
var err error
+ var lastCommand string
for _, command := range commandList {
cmd := browserCommand(command, url)
// Keep running commands from left to right until one of them exits
// successfully.
err = cmd.Run()
- if err == nil || cmd.ProcessState.ExitCode() == 0 {
- return err
+ if err == nil {
+ return nil
+ } else if cmd.ProcessState.ExitCode() == 0 {
+ return &ExecZeroError{command, err}
}
+
+ lastCommand = command
}
- return err
+ return &ExecError{lastCommand, err}
}
// browserCommand sets up an exec.Cmd to run command, attaching Stdout and
diff --git a/error.go b/error.go
new file mode 100644
index 0000000..d90d1b8
--- /dev/null
+++ b/error.go
@@ -0,0 +1,76 @@
+package browserenv
+
+import "fmt"
+
+const errorPrefix = "browserenv: "
+
+// CopyError represents a failure to copy data.
+type CopyError struct {
+ err error
+}
+
+func (e *CopyError) Error() string {
+ return fmt.Sprintf(errorPrefix+"can't copy from reader: %v", e.err)
+}
+
+func (e *CopyError) Unwrap() error { return e.err }
+
+// ExecError results from executing an external command.
+type ExecError struct {
+ command string
+ err error
+}
+
+func (e *ExecError) Error() string {
+ return fmt.Sprintf(
+ errorPrefix+"failed to run BROWSER command %q: %v",
+ e.command,
+ e.err,
+ )
+}
+
+func (e *ExecError) Unwrap() error { return e.err }
+
+// ExecZeroError results from executing an external command that produces an
+// error with an exit code of 0.
+type ExecZeroError struct {
+ command string
+ err error
+}
+
+func (e *ExecZeroError) Error() string {
+ return fmt.Sprintf(
+ errorPrefix+"error running command %q: %v",
+ e.command,
+ e.err,
+ )
+}
+
+func (e *ExecZeroError) Unwrap() error { return e.err }
+
+// PathResolutionError means the given path couldn't be resolved.
+type PathResolutionError struct {
+ path string
+ err error
+}
+
+func (e *PathResolutionError) Error() string {
+ return fmt.Sprintf(
+ errorPrefix+"can't resolve path for %q: %v",
+ e.path,
+ e.err,
+ )
+}
+
+func (e *PathResolutionError) Unwrap() error { return e.err }
+
+// TempFileError corresponds to an error while creating a temporary file.
+type TempFileError struct {
+ err error
+}
+
+func (e *TempFileError) Error() string {
+ return fmt.Sprintf(errorPrefix+"can't create temporary file: %v", e.err)
+}
+
+func (e *TempFileError) Unwrap() error { return e.err }