소스 검색

Added New and Cause methods.

Dave Cheney 10 년 전
부모
커밋
1e412a1049
4개의 변경된 파일128개의 추가작업 그리고 1개의 파일을 삭제
  1. 1 1
      LICENSE
  2. 35 0
      errors.go
  3. 79 0
      errors_test.go
  4. 13 0
      example_test.go

+ 1 - 1
LICENSE

@@ -1,4 +1,4 @@
-Copyright (c) 2015, 
+Copyright (c) 2015, Dave Cheney <dave@cheney.net>
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without

+ 35 - 0
errors.go

@@ -0,0 +1,35 @@
+// Package errors implements functions to manipulate errors.
+package errors
+
+type errorString string
+
+func (e errorString) Error() string {
+	return string(e)
+}
+
+// New returns an error that formats as the given text.
+func New(text string) error {
+	return errorString(text)
+}
+
+// Cause returns the underlying cause of the error, if possible.
+// An error value has a cause if it implements the following
+// method:
+//
+// Cause() error
+//
+//
+// If the error does not implement Cause, the original error will
+// be returned. If the error is nil, nil will be returned without further
+// investigation.
+func Cause(err error) error {
+	if err == nil {
+		return nil
+	}
+	if err, ok := err.(interface {
+		Cause() error
+	}); ok {
+		return err.Cause()
+	}
+	return err
+}

+ 79 - 0
errors_test.go

@@ -0,0 +1,79 @@
+package errors
+
+import (
+	"io"
+	"reflect"
+	"testing"
+)
+
+func TestNew(t *testing.T) {
+	got := New("test error")
+	want := errorString("test error")
+
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("New: got %#v, want %#v", got, want)
+	}
+}
+
+func TestNewError(t *testing.T) {
+	tests := []struct {
+		err  string
+		want error
+	}{
+		{"", errorString("")},
+		{"foo", errorString("foo")},
+		{"foo", New("foo")},
+	}
+
+	for _, tt := range tests {
+		got := New(tt.err)
+		if got.Error() != tt.want.Error() {
+			t.Errorf("New.Error(): got: %q, want %q", got, tt.want)
+		}
+	}
+}
+
+type nilError struct{}
+
+func (nilError) Error() string { return "nil error" }
+
+type causeError struct {
+	err error
+}
+
+func (e *causeError) Error() string { return "cause error" }
+func (e *causeError) Cause() error  { return e.err }
+
+func TestCause(t *testing.T) {
+	tests := []struct {
+		err  error
+		want error
+	}{{
+		// nil error is nil
+		err:  nil,
+		want: nil,
+	}, {
+		// explicit nil error is nil
+		err:  (error)(nil),
+		want: nil,
+	}, {
+		// typed nil is nil
+		err:  (*nilError)(nil),
+		want: (*nilError)(nil),
+	}, {
+		// uncaused error is unaffected
+		err:  io.EOF,
+		want: io.EOF,
+	}, {
+		// caused error returns cause
+		err:  &causeError{err: io.EOF},
+		want: io.EOF,
+	}}
+
+	for i, tt := range tests {
+		got := Cause(tt.err)
+		if !reflect.DeepEqual(got, tt.want) {
+			t.Errorf("test %d: got %#v, want %#v", i+1, got, tt.want)
+		}
+	}
+}

+ 13 - 0
example_test.go

@@ -0,0 +1,13 @@
+package errors_test
+
+import (
+	"errors"
+	"fmt"
+)
+
+func ExampleNew() {
+	err := errors.New("whoops")
+	fmt.Println(err.Error())
+
+	// Output: whoops
+}