Exemple #1
0
// Print implements internal logger Print method for logrus.
func (logrusWrapper *LogrusLogger) Print(v ...interface{}) {
	defer func() {
		if err := recover(); err != nil {
			stdlog.Panicf("Logging error: %v", err)
		}
	}()
	if len(v) == 0 {
		return
	}
	l := logrusWrapper.L
	if len(v) == 1 {
		if err, errOk := v[0].(error); errOk {
			if err2, err2Ok := fail.GetOriginalError(err).(*ErrDirectActionMethod); err2Ok {
				var stackTrace string
				if err3, err3Ok := err2.Err.(error); err3Ok {
					stackTrace = fail.GetStackTrace(err3)
				}

				if stackTrace == "" {
					stackTraceSkip := 1
					if err2.isPanic {
						stackTraceSkip = 4
					}
					stackTrace = fail.StackTrace(stackTraceSkip)
				}

				l = l.WithFields(logrus.Fields{
					"action": err2.Action,
					"method": err2.Method,
					"stack":  stackTrace,
				})
			} else {
				stackTrace := fail.GetStackTrace(err)
				if stackTrace == "" {
					stackTrace = fail.StackTrace(1)
				}

				l = l.WithFields(logrus.Fields{
					"stack": stackTrace,
				})
			}

			l.Error(err)
		} else {
			l.Debug(v[0])
		}
	} else {
		if len(v) > 2 {
			l = l.WithFields(v[2].(map[string]interface{}))
		}

		m := strings.TrimSpace(v[1].(string))
		logLevel := v[0].(string)
		switch logLevel {
		case logLevelInfo:
			l.Info(m)
		case logLevelWarn:
			l.Warn(m)
		default:
			panic(fmt.Errorf("Unknown log message type: '%v.", logLevel))
		}
	}
}
Exemple #2
0
func TestFail(t *testing.T) {
	Convey("Standard error", t, func() {
		err := errors.New("Error 1 occurred.")
		Convey("should have no inner", func() {
			So(fail.GetInner(err), ShouldBeNil)
		})
		Convey("should have no location", func() {
			So(fail.GetLocation(err), ShouldBeEmpty)
		})
		Convey("should have no stack trace", func() {
			So(fail.GetStackTrace(err), ShouldBeEmpty)
		})
		Convey("GetOriginalError() should return itself", func() {
			So(fail.GetOriginalError(err), ShouldEqual, err)
		})
		Convey("GetType() should return type of itself", func() {
			So(fail.GetType(err), ShouldEqual, reflect.TypeOf(err))
		})
	})

	Convey("Simple extended error", t, func() {
		errInner := errors.New("Error 1 occurred.")
		err := fail.New(errInner)
		Convey("should have correct message", func() {
			So(err.Error(), ShouldEqual, "Error 1 occurred.")
		})
		Convey("should have no inner", func() {
			So(fail.GetInner(err), ShouldBeNil)
		})
		Convey("should have correct location", func() {
			So(fail.GetLocation(err), ShouldContainSubstring, "github.com/nbgo/fail/fail_test.go:60")
			So(fail.GetLocation(err), ShouldContainSubstring, "TestFail.")
		})
		Convey("should have correct stack trace", func() {
			stackTrace := fail.GetStackTrace(err)
			So(stackTrace, ShouldContainSubstring, "TestFail.")
			So(stackTrace, ShouldContainSubstring, "fail_test.go:60")
			So(stackTrace, ShouldContainSubstring, "fail_test.go:77")
		})
	})

	Convey("Composite extended error", t, func() {
		err1 := fail.Newf("Error %v occurred.", 1)
		err2 := fail.News("Error 2 occurred.")
		err1c := fail.NewWithInner(err2, err1)
		err2c := fail.New(&MyError{"Error 3 occured", err1c})
		Convey("stack trace 1 check", func() {
			So(strings.Split(fail.GetStackTrace(err2c), "\n")[0], ShouldContainSubstring, "fail_test.go")
		})
		Convey("stack trace 2 check", func() {
			So(strings.Split(fail.GetStackTrace(err1c), "\n")[0], ShouldContainSubstring, "fail_test.go")
		})
		Convey("stack trace 3 check", func() {
			So(strings.Split(fail.GetStackTrace(err2), "\n")[0], ShouldContainSubstring, "fail_test.go")
		})
		Convey("stack trace 4 check", func() {
			So(strings.Split(fail.GetStackTrace(err1), "\n")[0], ShouldContainSubstring, "fail_test.go")
		})
		Convey("should have correct full details", func() {
			details := fail.GetFullDetails(err2c)
			fmt.Println("\n" + details)
			So(details, ShouldNotContainSubstring, "fail.extendedError")
		})
		Convey("should have correct message", func() {
			So(err2c.Error(), ShouldEqual, "MyError: Error 3 occured. Reason: Error 2 occurred.")
		})
		Convey("should have correct inner 1 level error", func() {
			inner := fail.GetInner(err2c)
			So(inner, ShouldNotBeNil)
			So(inner.Error(), ShouldEqual, "Error 2 occurred.")
			Convey("should have correct inner 2 level error", func() {
				inner2 := fail.GetInner(inner)
				So(inner2, ShouldNotBeNil)
				So(inner2.Error(), ShouldEqual, "Error 1 occurred.")
			})
		})
		Convey("GetOriginalError() should return correct error", func() {
			So(fail.GetOriginalError(err1c), ShouldEqual, fail.GetOriginalError(err2))
		})
	})

	Convey("ErrWithReason", t, func() {
		innerErr := fail.News("inner error")
		err := fail.NewErrWithReason("some error", innerErr)

		Convey("should have its own text and reason", func() {
			So(err.Error(), ShouldEqual, "some error: inner error")
		})

		Convey("should return correct inner error", func() {
			gotInnerErr := fail.GetInner(err)
			So(gotInnerErr, ShouldNotBeNil)
			So(gotInnerErr.Error(), ShouldEqual, "inner error")
			So(gotInnerErr, ShouldEqual, innerErr)
		})

		Convey("should have correct stack trace", func() {
			So(strings.Split(fail.GetStackTrace(err), "\n")[0], ShouldContainSubstring, "fail_test.go")
		})
	})

	Convey("StackTrace()", t, func() {
		stackTrace := fail.StackTrace()
		fmt.Println("\n" + stackTrace)
		So(strings.Split(stackTrace, "\n")[0], ShouldContainSubstring, "fail_test.go")

		func() {
			stackTrace := fail.StackTrace(1)
			fmt.Println("\n" + stackTrace)
			So(strings.Split(stackTrace, "\n")[0], ShouldContainSubstring, "fail_test.go")
		}()
	})

	Convey("IsError()", t, func() {
		innerErr := errors.New("test1")
		err2 := fail.NewErrWithReason("test2", innerErr)
		err3 := fail.NewErrWithReason("test3", err2)
		err4 := fail.News("test4")
		Convey("should return true when composite error has checked error in its hierarchy", func() {
			So(fail.IsError(err3, innerErr), ShouldBeTrue)
		})
		Convey("should return true when checked error is itself", func() {
			So(fail.IsError(innerErr, innerErr), ShouldBeTrue)
		})
		Convey("should return false when composite error does not have checked error in its hierarchy", func() {
			So(fail.IsError(err4, innerErr), ShouldBeFalse)
		})
	})

	Convey("AreErrorsOfEqualType()", t, func() {
		err1 := &MyError{}
		err2 := &MyError{}
		err3 := MyError{}
		err4 := fail.News("test")
		So(fail.AreErrorsOfEqualType(err1, err2), ShouldBeTrue)
		So(fail.AreErrorsOfEqualType(err1, err3), ShouldBeTrue)
		So(fail.AreErrorsOfEqualType(err3, err2), ShouldBeTrue)
		So(fail.AreErrorsOfEqualType(err1, err4), ShouldBeFalse)
		So(fail.AreErrorsOfEqualType(err3, err4), ShouldBeFalse)
	})

	Convey("GetErrorByType()", t, func() {
		innerErr := &MyError{}
		err2 := fail.NewErrWithReason("test2", innerErr)
		err3 := fail.NewErrWithReason("test3", err2)
		err4 := fail.News("test4")
		So(fail.GetErrorByType(err3, MyError{}), ShouldEqual, innerErr)
		So(fail.GetErrorByType(err4, MyError{}), ShouldBeNil)
	})

	Convey("ErrWithFields", t, func() {
		err := fail.New(fail.New(MyErrWithFields{"p1", "p2"}))
		So(err.Error(), ShouldEqual, "This is an error with fields: p1, p2")
		errWithFields := err.(fail.ErrorWithFields)
		fields := errWithFields.Fields()
		So(fields, ShouldNotBeNil)
		So(errWithFields.Fields(), ShouldResemble, map[string]interface{}{"param1": "p1", "param2": "p2"})

		err = fail.News("test")
		errWithFields = err.(fail.ErrorWithFields)
		fields = errWithFields.Fields()
		So(fields, ShouldBeNil)
	})

}