Commit 31661766 authored by Kirill Smelkov's avatar Kirill Smelkov

exc: Contextf

A shorthand for when exception context is just formatted string.
Simplifies

	func doSomething(path string) {
		defer exc.Context(func() interface{} {
			return fmt.Sprintf("doing something %s", path)
		})()
		...

to

	func doSomething(path string) {
		defer exc.Contextf("doing something %s", path)
		...
parent a281a51c
// Copyright (C) 2015-2019 Nexedi SA and Contributors. // Copyright (C) 2015-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com> // Kirill Smelkov <kirr@nexedi.com>
// //
// This program is free software: you can Use, Study, Modify and Redistribute // This program is free software: you can Use, Study, Modify and Redistribute
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
// Raise and Catch allow to raise and catch exceptions. // Raise and Catch allow to raise and catch exceptions.
// //
// By default the error caught is the same error that was raised. However with // By default the error caught is the same error that was raised. However with
// Context functions can arrange for context related to what they are doing to // Context* functions can arrange for context related to what they are doing to
// be added to raised error as prefix, for example // be added to raised error as prefix, for example
// //
// func doSomething(path string) { // func doSomething(path string) {
...@@ -30,6 +30,11 @@ ...@@ -30,6 +30,11 @@
// return fmt.Sprintf("doing something %s", path) // return fmt.Sprintf("doing something %s", path)
// })() // })()
// //
// or
//
// func doSomething(path string) {
// defer exc.Contextf("doing something %s", path)
// ...
// //
// Lacking such Context annotations Addcallingcontext allows to add function // Lacking such Context annotations Addcallingcontext allows to add function
// names up to the exception point as the calling context. However this way // names up to the exception point as the calling context. However this way
...@@ -175,6 +180,20 @@ func Context(f func() interface{}) { ...@@ -175,6 +180,20 @@ func Context(f func() interface{}) {
panic(Addcontext(e, arg)) panic(Addcontext(e, arg))
} }
// Contextf provides formatted string to be added to error as context on unwinding.
//
// It is shorthand for Context wrapping fmt.Sprintf.
//
// Must be called under defer.
func Contextf(format string, argv ...interface{}) {
e := _errcatch(recover())
if e == nil {
return
}
panic(Addcontext(e, fmt.Sprintf(format, argv...)))
}
// Addcontext adds "prefix" context to error. // Addcontext adds "prefix" context to error.
func Addcontext(e *Error, arg interface{}) *Error { func Addcontext(e *Error, arg interface{}) *Error {
return &Error{arg, e} return &Error{arg, e}
......
// Copyright (C) 2015-2017 Nexedi SA and Contributors. // Copyright (C) 2015-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com> // Kirill Smelkov <kirr@nexedi.com>
// //
// This program is free software: you can Use, Study, Modify and Redistribute // This program is free software: you can Use, Study, Modify and Redistribute
...@@ -104,6 +104,25 @@ func TestErrContext(t *testing.T) { ...@@ -104,6 +104,25 @@ func TestErrContext(t *testing.T) {
t.Fatal("error not caught") t.Fatal("error not caught")
} }
func do_contextf1() {
defer Contextf("must not be added")
return // no exception
}
func do_contextf2() {
defer Contextf("hello %d world", 123)
do_raise1()
}
func TestErrContextf(t *testing.T) {
defer Catch(func(e *Error) {
verifyErrChain(t, e, "hello 123 world", 1)
})
do_contextf1()
do_contextf2()
t.Fatal("error not caught")
}
func do_raise11() { func do_raise11() {
do_raise1() do_raise1()
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment