Repository: goadesign/goa
Pull request #2596 (2020-06-16 13:40:50)

"struct:error:name" and "struct:field:name" not work together
Following code 
```go
var Result = ResultType("application/vnd.goa.error", func() {
    Attribute("error", String, func() {
        Meta("struct:error:name")
        Meta("struct:field:name", "ErrorCode")
    })
    Required("error")
})
```
Generated code:
```go
type GoaError struct {
    ErrorCode string
}

// Error returns an error description.
func (e *GoaError) Error() string {
    return ""
}

// ErrorName returns "GoaError".
func (e *GoaError) ErrorName() string {
    return e.Error
}

```
This code won't be compiled:
```
cannot use e.Error (type func() string) as type string in return argument
```

See full example of DSL and generated code in tests below.

raphael: Good catch! thank you. Can you please back-port to the `v2` branch as well? (simply cherry-pick the merge commit).

Patch:
diff --git a/codegen/service/service.go b/codegen/service/service.go
index 461aa606..b61a92b7 100644
--- a/codegen/service/service.go
+++ b/codegen/service/service.go
@@ -173,7 +173,7 @@ func errorName(et *UserTypeData) string {
 	if obj != nil {
 		for _, att := range *obj {
 			if _, ok := att.Attribute.Meta["struct:error:name"]; ok {
-				return fmt.Sprintf("e.%s", codegen.Goify(att.Name, true))
+				return fmt.Sprintf("e.%s", codegen.GoifyAtt(att.Attribute, att.Name, true))
 			}
 		}
 	}


Test patch:
diff --git a/codegen/service/service_test.go b/codegen/service/service_test.go
index 7bb94380..a591dc78 100644
--- a/codegen/service/service_test.go
+++ b/codegen/service/service_test.go
@@ -30,6 +30,7 @@ func TestService(t *testing.T) {
 		{"result-with-result-collection", testdata.ResultWithResultCollectionMethodDSL, testdata.ResultWithResultCollectionMethod},
 		{"service-level-error", testdata.ServiceErrorDSL, testdata.ServiceError},
 		{"custom-errors", testdata.CustomErrorsDSL, testdata.CustomErrors},
+		{"custom-errors-custom-field", testdata.CustomErrorsCustomFieldDSL, testdata.CustomErrorsCustomField},
 		{"force-generate-type", testdata.ForceGenerateTypeDSL, testdata.ForceGenerateType},
 		{"force-generate-type-explicit", testdata.ForceGenerateTypeExplicitDSL, testdata.ForceGenerateTypeExplicit},
 		{"streaming-result", testdata.StreamingResultMethodDSL, testdata.StreamingResultMethod},
diff --git a/codegen/service/testdata/service_code.go b/codegen/service/testdata/service_code.go
index 39f84649..7c9090cd 100644
--- a/codegen/service/testdata/service_code.go
+++ b/codegen/service/testdata/service_code.go
@@ -362,6 +362,38 @@ func (e *Result) ErrorName() string {
 }
 `
 
+const CustomErrorsCustomField = `
+// Service is the CustomErrorsCustomFields service interface.
+type Service interface {
+	// A implements A.
+	A(context.Context) (err error)
+}
+
+// ServiceName is the name of the service as defined in the design. This is the
+// same value that is set in the endpoint request contexts under the ServiceKey
+// key.
+const ServiceName = "CustomErrorsCustomFields"
+
+// MethodNames lists the service method names as defined in the design. These
+// are the same values that are set in the endpoint request contexts under the
+// MethodKey key.
+var MethodNames = [1]string{"A"}
+
+type GoaError struct {
+	ErrorCode string
+}
+
+// Error returns an error description.
+func (e *GoaError) Error() string {
+	return ""
+}
+
+// ErrorName returns "GoaError".
+func (e *GoaError) ErrorName() string {
+	return e.ErrorCode
+}
+`
+
 const MultipleMethodsResultMultipleViews = `
 // Service is the MultipleMethodsResultMultipleViews service interface.
 type Service interface {
diff --git a/codegen/service/testdata/service_dsls.go b/codegen/service/testdata/service_dsls.go
index 70af7e6f..5a856106 100644
--- a/codegen/service/testdata/service_dsls.go
+++ b/codegen/service/testdata/service_dsls.go
@@ -149,6 +149,21 @@ var CustomErrorsDSL = func() {
 	})
 }
 
+var CustomErrorsCustomFieldDSL = func() {
+	var Result = ResultType("application/vnd.goa.error", func() {
+		Attribute("error", String, func() {
+			Meta("struct:error:name")
+			Meta("struct:field:name", "ErrorCode")
+		})
+		Required("error")
+	})
+	Service("CustomErrorsCustomFields", func() {
+		Method("A", func() {
+			Error("struct_error_name", Result, "struct error name description")
+		})
+	})
+}
+
 var MultipleMethodsResultMultipleViewsDSL = func() {
 	var RTWithViews = ResultType("application/vnd.result.multiple.views", func() {
 		TypeName("MultipleViews")