@cryptotaxi247 / kubo / commits / 519863eca

fix(core/node): unwrap fx error in node construction

Lucas Molas committed Jan 5, 2022 at 11:25 UTC 519863ecab4db26d33d9a4af8f5284acf4b5ca29
4 files changed +51 -4
cmd/ipfs/daemon.go
-1
@@ -427,7 +427,6 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
427
428 node, err := core.NewNode(req.Context, ncfg)
429 if err != nil {
430 - log.Error("error from node construction: ", err)
430 return err
431 }
432 node.IsDaemon = true
core/builder.go
+48 -2
@@ -2,6 +2,8 @@ package core
2
3 import (
4 "context"
5 + "fmt"
6 + "reflect"
7 "sync"
8 "time"
9
@@ -9,6 +11,7 @@ import (
11 "github.com/ipfs/go-ipfs/core/node"
12
13 "github.com/ipfs/go-metrics-interface"
14 + "go.uber.org/dig"
15 "go.uber.org/fx"
16 )
17
@@ -75,11 +78,11 @@ func NewNode(ctx context.Context, cfg *BuildCfg) (*IpfsNode, error) {
78 }()
79
80 if app.Err() != nil {
78 - return nil, app.Err()
81 + return nil, logAndUnwrapFxError(app.Err())
82 }
83
84 if err := app.Start(ctx); err != nil {
82 - return nil, err
85 + return nil, logAndUnwrapFxError(err)
86 }
87
88 // TODO: How soon will bootstrap move to libp2p?
@@ -89,3 +92,46 @@ func NewNode(ctx context.Context, cfg *BuildCfg) (*IpfsNode, error) {
92
93 return n, n.Bootstrap(bootstrap.DefaultBootstrapConfig)
94 }
95 +
96 +// Log the entire `app.Err()` but return only the innermost one to the user
97 +// given the full error can be very long (as it can expose the entire build
98 +// graph in a single string).
99 +//
100 +// The fx.App error exposed through `app.Err()` normally contains un-exported
101 +// errors from its low-level `dig` package:
102 +// * https://github.com/uber-go/dig/blob/5e5a20d/error.go#L82
103 +// These usually wrap themselves in many layers to expose where in the build
104 +// chain did the error happen. Although useful for a developer that needs to
105 +// debug it, it can be very confusing for a user that just wants the IPFS error
106 +// that he can probably fix without being aware of the entire chain.
107 +// Unwrapping everything is not the best solution as there can be useful
108 +// information in the intermediate errors, mainly in the next to last error
109 +// that locates which component is the build error coming from, but it's the
110 +// best we can do at the moment given all errors in dig are private and we
111 +// just have the generic `RootCause` API.
112 +func logAndUnwrapFxError(fxAppErr error) error {
113 + if fxAppErr == nil {
114 + return nil
115 + }
116 +
117 + log.Error("constructing the node: ", fxAppErr)
118 +
119 + err := fxAppErr
120 + for {
121 + extractedErr := dig.RootCause(err)
122 + // Note that the `RootCause` name is misleading as it just unwraps only
123 + // *one* error layer at a time, so we need to continuously call it.
124 + if !reflect.TypeOf(extractedErr).Comparable() {
125 + // Some internal errors are not comparable (e.g., `dig.errMissingTypes`
126 + // which is a slice) and we can't go further.
127 + break
128 + }
129 + if extractedErr == err {
130 + // We didn't unwrap any new error in the last call, reached the innermost one.
131 + break
132 + }
133 + err = extractedErr
134 + }
135 +
136 + return fmt.Errorf("constructing the node (see log for full detail): %w", err)
137 +}
go.mod
+1
@@ -104,6 +104,7 @@ require (
104 github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1
105 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7
106 go.opencensus.io v0.23.0
107 + go.uber.org/dig v1.14.0
108 go.uber.org/fx v1.16.0
109 go.uber.org/zap v1.21.0
110 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
go.sum
+2 -1
@@ -1418,8 +1418,9 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
1418 go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
1419 go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
1420 go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
1421 -go.uber.org/dig v1.12.0 h1:l1GQeZpEbss0/M4l/ZotuBndCrkMdjnygzgcuOjAdaY=
1421 go.uber.org/dig v1.12.0/go.mod h1:X34SnWGr8Fyla9zQNO2GSO2D+TIuqB14OS8JhYocIyw=
1422 +go.uber.org/dig v1.14.0 h1:VmGvIH45/aapXPQkaOrK5u4B5B7jxZB98HM/utx0eME=
1423 +go.uber.org/dig v1.14.0/go.mod h1:jHAn/z1Ld1luVVyGKOAIFYz/uBFqKjjEEdIqVAqfQ2o=
1424 go.uber.org/fx v1.16.0 h1:N8i80+X1DCX+qMRiKzM+jPPZiIiyK/bVCysga3+B+1w=
1425 go.uber.org/fx v1.16.0/go.mod h1:OMoT5BnXcOaiexlpjtpE4vcAmzyDKyRs9TRYXCzamx8=
1426 go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=