bigquery: improve error messages in bigquery.PutMultiError to show its details

Change-Id: I2bbdc42c35346f7f7782d4f1850645f574dbb017
Reviewed-on: https://code-review.googlesource.com/c/gocloud/+/52230
Reviewed-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Seth Hollyman <shollyman@google.com>
diff --git a/bigquery/error.go b/bigquery/error.go
index 27e8698..cab9b00 100644
--- a/bigquery/error.go
+++ b/bigquery/error.go
@@ -16,6 +16,7 @@
 
 import (
 	"fmt"
+	"strings"
 
 	bq "google.golang.org/api/bigquery/v2"
 )
@@ -73,11 +74,33 @@
 // into a BigQuery table.
 type PutMultiError []RowInsertionError
 
+func (pme PutMultiError) errorDetails() string {
+	size := len(pme)
+	ellipsis := ""
+	if size == 0 {
+		return ""
+	} else if size > 3 {
+		size = 3
+		ellipsis = ", ..."
+	}
+
+	es := make([]string, size)
+	for i, e := range pme {
+		if i >= size {
+			break
+		}
+		es[i] = e.Error()
+	}
+
+	return fmt.Sprintf(" (%s%s)", strings.Join(es, ", "), ellipsis)
+}
+
 func (pme PutMultiError) Error() string {
 	plural := "s"
 	if len(pme) == 1 {
 		plural = ""
 	}
 
-	return fmt.Sprintf("%v row insertion%s failed", len(pme), plural)
+	details := pme.errorDetails()
+	return fmt.Sprintf("%v row insertion%s failed%s", len(pme), plural, details)
 }
diff --git a/bigquery/error_test.go b/bigquery/error_test.go
index 7442f62..7858ea3 100644
--- a/bigquery/error_test.go
+++ b/bigquery/error_test.go
@@ -38,11 +38,16 @@
 		},
 		{
 			errs: PutMultiError{rowInsertionError("a")},
-			want: "1 row insertion failed",
+			want: "1 row insertion failed (insertion of row [insertID: \"\"; insertIndex: 0] failed with error: a)",
 		},
 		{
-			errs: PutMultiError{rowInsertionError("a"), rowInsertionError("b")},
-			want: "2 row insertions failed",
+			errs: PutMultiError{
+				rowInsertionError("1"),
+				rowInsertionError("2"),
+				rowInsertionError("3"),
+				rowInsertionError("4"),
+			},
+			want: "4 row insertions failed (insertion of row [insertID: \"\"; insertIndex: 0] failed with error: 1, insertion of row [insertID: \"\"; insertIndex: 0] failed with error: 2, insertion of row [insertID: \"\"; insertIndex: 0] failed with error: 3, ...)",
 		},
 	}