Repository: goadesign/goa
Pull request #3280 (2023-04-14 21:12:02)

Properly handle query string slice decoding
When the request is multipart. In this case the code should only return a single value. Make both cases work by following the common pattern of setting the error and not returning right away.

raphael: Fix https://github.com/goadesign/goa/issues/3278

Patch:
diff --git a/README.md b/README.md
index 557e65a9..bf7a4d58 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,8 @@
 [![GoDev](https://img.shields.io/badge/go-reference-007d9c?logo=go&logoColor=white&style=flat-square)](https://pkg.go.dev/goa.design/goa/v3@v3.11.3/dsl?tab=doc)
 [![Foresight](https://api-public.service.runforesight.com/api/v1/badge/test?repoId=67defc2e-b3f8-4043-bac7-a4e215518ed3)](http://goa.app.runforesight.com/)
 [![Go Report Card](https://goreportcard.com/badge/goadesign/goa)](https://goreportcard.com/report/goadesign/goa)
-[![Slack](https://img.shields.io/badge/Slack-gray.svg?longCache=true&logo=slack&colorB=red)](https://gophers.slack.com/messages/goa)
+[![Slack](https://img.shields.io/badge/Goa-gray.svg?longCache=true&logo=slack&colorB=red)](https://gophers.slack.com/messages/goa)
+[![Signup](https://img.shields.io/badge/Signup-gray.svg?longCache=true&logo=slack&colorB=red)](https://invite.slack.golangbridge.org/)
 [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/goadesign.svg?style=social)](https://twitter.com/goadesign)
 
 Goa takes a different approach to building services by making it possible to
diff --git a/http/codegen/server.go b/http/codegen/server.go
index 66173786..c7dc0437 100644
--- a/http/codegen/server.go
+++ b/http/codegen/server.go
@@ -704,7 +704,7 @@ const requestElementsT = `{{- define "request_elements" }}
 		{{ .VarName }}Raw := r.URL.Query()["{{ .Name }}"]
 		{{- if .Required }}
 		if {{ .VarName }}Raw == nil {
-			return nil, goa.MergeErrors(err, goa.MissingFieldError("{{ .Name }}", "query string"))
+			err = goa.MergeErrors(err, goa.MissingFieldError("{{ .Name }}", "query string"))
 		}
 		{{- else if .DefaultValue }}
 		if {{ .VarName }}Raw == nil {


Test patch:
diff --git a/http/codegen/testdata/payload_decode_functions.go b/http/codegen/testdata/payload_decode_functions.go
index 34f70001..564c3be3 100644
--- a/http/codegen/testdata/payload_decode_functions.go
+++ b/http/codegen/testdata/payload_decode_functions.go
@@ -750,7 +750,7 @@ func DecodeMethodQueryArrayBoolValidateRequest(mux goahttp.Muxer, decoder func(*
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([]bool, len(qRaw))
 			for i, rv := range qRaw {
@@ -821,7 +821,7 @@ func DecodeMethodQueryArrayIntValidateRequest(mux goahttp.Muxer, decoder func(*h
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([]int, len(qRaw))
 			for i, rv := range qRaw {
@@ -893,7 +893,7 @@ func DecodeMethodQueryArrayInt32ValidateRequest(mux goahttp.Muxer, decoder func(
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([]int32, len(qRaw))
 			for i, rv := range qRaw {
@@ -965,7 +965,7 @@ func DecodeMethodQueryArrayInt64ValidateRequest(mux goahttp.Muxer, decoder func(
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([]int64, len(qRaw))
 			for i, rv := range qRaw {
@@ -1037,7 +1037,7 @@ func DecodeMethodQueryArrayUIntValidateRequest(mux goahttp.Muxer, decoder func(*
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([]uint, len(qRaw))
 			for i, rv := range qRaw {
@@ -1109,7 +1109,7 @@ func DecodeMethodQueryArrayUInt32ValidateRequest(mux goahttp.Muxer, decoder func
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([]uint32, len(qRaw))
 			for i, rv := range qRaw {
@@ -1181,7 +1181,7 @@ func DecodeMethodQueryArrayUInt64ValidateRequest(mux goahttp.Muxer, decoder func
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([]uint64, len(qRaw))
 			for i, rv := range qRaw {
@@ -1253,7 +1253,7 @@ func DecodeMethodQueryArrayFloat32ValidateRequest(mux goahttp.Muxer, decoder fun
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([]float32, len(qRaw))
 			for i, rv := range qRaw {
@@ -1325,7 +1325,7 @@ func DecodeMethodQueryArrayFloat64ValidateRequest(mux goahttp.Muxer, decoder fun
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([]float64, len(qRaw))
 			for i, rv := range qRaw {
@@ -1435,7 +1435,7 @@ func DecodeMethodQueryArrayBytesValidateRequest(mux goahttp.Muxer, decoder func(
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([][]byte, len(qRaw))
 			for i, rv := range qRaw {
@@ -1494,7 +1494,7 @@ func DecodeMethodQueryArrayAnyValidateRequest(mux goahttp.Muxer, decoder func(*h
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([]any, len(qRaw))
 			for i, rv := range qRaw {
@@ -2431,7 +2431,7 @@ func DecodeMethodQueryPrimitiveArrayBoolValidateRequest(mux goahttp.Muxer, decod
 		{
 			qRaw := r.URL.Query()["q"]
 			if qRaw == nil {
-				return nil, goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
+				err = goa.MergeErrors(err, goa.MissingFieldError("q", "query string"))
 			}
 			q = make([]bool, len(qRaw))
 			for i, rv := range qRaw {