From aff91f7b260cd571f0309ef80615f14e11a3d567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Mon, 26 Apr 2021 15:37:24 +0100 Subject: [PATCH] fluent/qp: don't panic on string panics Since qp uses panics as an error mechanism, the top-level functions recover those errors to return them normally. However, this blows up if, internally, an ipld.Node implementation panics with a value whose type is not error. For example, with: panic("some panic message") One gets: panic: some panic message [recovered] panic: interface conversion: string is not error: missing method Error Fix this by having a fallback for non-error panic values. --- fluent/qp/qp.go | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fluent/qp/qp.go b/fluent/qp/qp.go index 5b60800..9362f6f 100644 --- a/fluent/qp/qp.go +++ b/fluent/qp/qp.go @@ -2,6 +2,8 @@ package qp import ( + "fmt" + "github.com/ipld/go-ipld-prime" ) @@ -10,7 +12,12 @@ type Assemble = func(ipld.NodeAssembler) func BuildMap(np ipld.NodePrototype, sizeHint int64, fn func(ipld.MapAssembler)) (_ ipld.Node, err error) { defer func() { if r := recover(); r != nil { - err = r.(error) + if rerr, ok := r.(error); ok { + err = rerr + } else { + // A reasonable fallback, for e.g. strings. + err = fmt.Errorf("%v", r) + } } }() nb := np.NewBuilder() @@ -49,7 +56,12 @@ func MapEntry(ma ipld.MapAssembler, k string, fn Assemble) { func BuildList(np ipld.NodePrototype, sizeHint int64, fn func(ipld.ListAssembler)) (_ ipld.Node, err error) { defer func() { if r := recover(); r != nil { - err = r.(error) + if rerr, ok := r.(error); ok { + err = rerr + } else { + // A reasonable fallback, for e.g. strings. + err = fmt.Errorf("%v", r) + } } }() nb := np.NewBuilder() -- GitLab