@cryptotaxi247 / kubo / commits / 63a2855a4

feat(util:context) add error logging to context

This commit... is a second attempt at: https://github.com/jbenet/go-ipfs/pull/68 partially addresses: https://github.com/jbenet/go-ipfs/issues/66 is the result of discussion at: https://gist.github.com/perfmode/f2951c1ed3a02c484d0b

Brian Tiger Chow committed Sep 23, 2014 at 16:41 UTC 63a2855a49df0492090416004f8a56fa05845405
2 files changed +63
util/context.go new
+35
@@ -0,0 +1,35 @@
1 +package util
2 +
3 +import (
4 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
5 +)
6 +
7 +// privateChanType protects the channel. Since this is a package-private type,
8 +// only methods defined in this package can get the error value from the
9 +// context.
10 +type privateChanType chan error
11 +
12 +const errLogKey = "the key used to extract the error log from the context"
13 +
14 +// ContextWithErrorLog returns a copy of parent and an error channel that can
15 +// be used to receive errors sent with the LogError method.
16 +func ContextWithErrorLog(parent context.Context) (context.Context, <-chan error) {
17 + errs := make(privateChanType)
18 + ctx := context.WithValue(parent, errLogKey, errs)
19 + return ctx, errs
20 +}
21 +
22 +// LogError logs the error to the owner of the context.
23 +//
24 +// If this context was created with ContextWithErrorLog, then this method
25 +// passes the error to context creator over an unbuffered channel.
26 +//
27 +// If this context was created by other means, this method is a no-op.
28 +func LogError(ctx context.Context, err error) {
29 + v := ctx.Value(errLogKey)
30 + errs, ok := v.(privateChanType)
31 + if !ok {
32 + return
33 + }
34 + errs <- err
35 +}
util/context_test.go new
+28
@@ -0,0 +1,28 @@
1 +package util
2 +
3 +import (
4 + "errors"
5 + "testing"
6 +
7 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
8 +)
9 +
10 +func TestLogErrorDoesNotBlockWhenCtxIsNotSetUpForLogging(t *testing.T) {
11 + ctx := context.Background()
12 + LogError(ctx, errors.New("ignore me"))
13 +}
14 +
15 +func TestLogErrorReceivedByParent(t *testing.T) {
16 +
17 + expected := errors.New("From child to parent")
18 +
19 + ctx, errs := ContextWithErrorLog(context.Background())
20 +
21 + go func() {
22 + LogError(ctx, expected)
23 + }()
24 +
25 + if err := <-errs; err != expected {
26 + t.Fatal("didn't receive the expected error")
27 + }
28 +}