sync/errgroup: PanicError.Error print stack trace

Because it is useful to print the stack
when a nil pointer dereference occurs.

Fixes golang/go#73710

Change-Id: I106ea0bdd70c2a293f5ea889edef9b5ba9db2fbd
Reviewed-on: https://go-review.googlesource.com/c/sync/+/672635
Reviewed-by: Damien Neil <dneil@google.com>
Auto-Submit: Damien Neil <dneil@google.com>
Auto-Submit: Alan Donovan <adonovan@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
TryBot-Bypass: Damien Neil <dneil@google.com>
diff --git a/errgroup/errgroup.go b/errgroup/errgroup.go
index cfafed5..a6b6ad2 100644
--- a/errgroup/errgroup.go
+++ b/errgroup/errgroup.go
@@ -185,8 +185,9 @@
 }
 
 func (p PanicError) Error() string {
-	// A Go Error method conventionally does not include a stack dump, so omit it
-	// here. (Callers who care can extract it from the Stack field.)
+	if len(p.Stack) > 0 {
+		return fmt.Sprintf("recovered from errgroup.Group: %v\n%s", p.Recovered, p.Stack)
+	}
 	return fmt.Sprintf("recovered from errgroup.Group: %v", p.Recovered)
 }
 
diff --git a/errgroup/errgroup_test.go b/errgroup/errgroup_test.go
index 4684259..2165bb7 100644
--- a/errgroup/errgroup_test.go
+++ b/errgroup/errgroup_test.go
@@ -309,9 +309,9 @@
 			if pe.Recovered != p {
 				t.Fatalf("got %v, want %v", pe.Recovered, p)
 			}
-			if !strings.Contains(string(pe.Stack), "TestPanic.func") {
-				t.Log(string(pe.Stack))
-				t.Fatalf("stack trace incomplete")
+			if !strings.Contains(pe.Error(), "TestPanic.func") {
+				t.Log(pe.Error())
+				t.Fatalf("stack trace incomplete, does not contain TestPanic.func")
 			}
 		}()
 		g.Wait()