Browse Source

Merge pull request #2 from adrienkohlbecker/master

Enable wrapping errors while prefixing the error message.
Conrad Irwin 10 years ago
parent
commit
a418503806
2 changed files with 55 additions and 1 deletions
  1. 28 1
      error.go
  2. 27 0
      error_test.go

+ 28 - 1
error.go

@@ -61,6 +61,7 @@ type Error struct {
 	Err    error
 	stack  []uintptr
 	frames []StackFrame
+	prefix string
 }
 
 // New makes an Error from the given value. If that value is already an
@@ -109,6 +110,26 @@ func Wrap(e interface{}, skip int) *Error {
 	}
 }
 
+// WrapPrefix makes an Error from the given value. If that value is already an
+// error then it will be used directly, if not, it will be passed to
+// fmt.Errorf("%v"). The prefix parameter is used to add a prefix to the
+// error message when calling Error(). The skip parameter indicates how far
+// up the stack to start the stacktrace. 0 is from the current call,
+// 1 from its caller, etc.
+func WrapPrefix(e interface{}, prefix string, skip int) *Error {
+
+	err := Wrap(e, skip)
+
+	if err.prefix != "" {
+		err.prefix = fmt.Sprintf("%s: %s", prefix, err.prefix)
+	} else {
+		err.prefix = prefix
+	}
+
+	return err
+
+}
+
 // Is detects whether the error is equal to a given error. Errors
 // are considered equal by this function if they are the same object,
 // or if they both contain the same error inside an errors.Error.
@@ -138,7 +159,13 @@ func Errorf(format string, a ...interface{}) *Error {
 
 // Error returns the underlying error's message.
 func (err *Error) Error() string {
-	return err.Err.Error()
+
+	msg := err.Err.Error()
+	if err.prefix != "" {
+		msg = fmt.Sprintf("%s: %s", err.prefix, msg)
+	}
+
+	return msg
 }
 
 // Stack returns the callstack formatted the same way that go does

+ 27 - 0
error_test.go

@@ -133,6 +133,33 @@ func TestWrapError(t *testing.T) {
 	}
 }
 
+func TestWrapPrefixError(t *testing.T) {
+
+	e := func() error {
+		return WrapPrefix("hi", "prefix", 1)
+	}()
+
+	fmt.Println(e.Error())
+	if e.Error() != "prefix: hi" {
+		t.Errorf("Constructor with a string failed")
+	}
+
+	if WrapPrefix(fmt.Errorf("yo"), "prefix", 0).Error() != "prefix: yo" {
+		t.Errorf("Constructor with an error failed")
+	}
+
+	prefixed := WrapPrefix(e, "prefix", 0)
+	original := e.(*Error)
+
+	if prefixed.Err != original.Err || &prefixed.stack != &original.stack || &prefixed.frames != &original.frames || prefixed.Error() != "prefix: prefix: hi" {
+		t.Errorf("Constructor with an Error failed")
+	}
+
+	if WrapPrefix(nil, "prefix", 0).Error() != "prefix: <nil>" {
+		t.Errorf("Constructor with nil failed")
+	}
+}
+
 func ExampleErrorf(x int) (int, error) {
 	if x%2 == 1 {
 		return 0, Errorf("can only halve even numbers, got %d", x)