summaryrefslogtreecommitdiffstats
path: root/plugin/interface_generator
diff options
context:
space:
mode:
authorJesse Hallam <jesse.hallam@gmail.com>2018-09-13 14:31:22 -0400
committerChristopher Speller <crspeller@gmail.com>2018-09-13 11:31:22 -0700
commitf2ddef9117712508234b85583c240cc856141980 (patch)
tree30e43360e83667898bf9b75f85179441c0b6872e /plugin/interface_generator
parent8b17bf9e42dd56ecd0fe8300da90bea5ee8684ef (diff)
downloadchat-f2ddef9117712508234b85583c240cc856141980.tar.gz
chat-f2ddef9117712508234b85583c240cc856141980.tar.bz2
chat-f2ddef9117712508234b85583c240cc856141980.zip
MM-11734: better plugin `error` handling (#9405)
* MM-11734: encode unregistered error implementations as an ErrorString * MM-11734: test error string handling * more idiomatic error handling
Diffstat (limited to 'plugin/interface_generator')
-rw-r--r--plugin/interface_generator/main.go45
1 files changed, 43 insertions, 2 deletions
diff --git a/plugin/interface_generator/main.go b/plugin/interface_generator/main.go
index 6aa8bdfb1..95977713e 100644
--- a/plugin/interface_generator/main.go
+++ b/plugin/interface_generator/main.go
@@ -69,6 +69,43 @@ func FieldListToNames(fieldList *ast.FieldList, fileset *token.FileSet) string {
return strings.Join(result, ", ")
}
+func FieldListToEncodedErrors(structPrefix string, fieldList *ast.FieldList, fileset *token.FileSet) string {
+ result := []string{}
+ if fieldList == nil {
+ return ""
+ }
+
+ nextLetter := 'A'
+ for _, field := range fieldList.List {
+ typeNameBuffer := &bytes.Buffer{}
+ err := printer.Fprint(typeNameBuffer, fileset, field.Type)
+ if err != nil {
+ panic(err)
+ }
+
+ if typeNameBuffer.String() != "error" {
+ nextLetter += 1
+ continue
+ }
+
+ name := ""
+ if len(field.Names) == 0 {
+ name = string(nextLetter)
+ nextLetter += 1
+ } else {
+ for range field.Names {
+ name += string(nextLetter)
+ nextLetter += 1
+ }
+ }
+
+ result = append(result, structPrefix+name+" = encodableError("+structPrefix+name+")")
+
+ }
+
+ return strings.Join(result, "\n")
+}
+
func FieldListDestruct(structPrefix string, fieldList *ast.FieldList, fileset *token.FileSet) string {
result := []string{}
if fieldList == nil || len(fieldList.List) == 0 {
@@ -237,8 +274,9 @@ func (s *hooksRPCServer) {{.Name}}(args *{{.Name | obscure}}Args, returns *{{.Na
{{.Name}}{{funcStyle .Params}} {{funcStyle .Return}}
}); ok {
{{if .Return}}{{destruct "returns." .Return}} = {{end}}hook.{{.Name}}({{destruct "args." .Params}})
+ {{if .Return}}{{encodeErrors "returns." .Return}}{{end}}
} else {
- return fmt.Errorf("Hook {{.Name}} called but not implemented.")
+ return encodableError(fmt.Errorf("Hook {{.Name}} called but not implemented."))
}
return nil
}
@@ -269,7 +307,7 @@ func (s *apiRPCServer) {{.Name}}(args *{{.Name | obscure}}Args, returns *{{.Name
}); ok {
{{if .Return}}{{destruct "returns." .Return}} = {{end}}hook.{{.Name}}({{destruct "args." .Params}})
} else {
- return fmt.Errorf("API {{.Name}} called but not implemented.")
+ return encodableError(fmt.Errorf("API {{.Name}} called but not implemented."))
}
return nil
}
@@ -292,6 +330,9 @@ func generateGlue(info *PluginInterfaceInfo) {
"funcStyle": func(fields *ast.FieldList) string { return FieldListToFuncList(fields, info.FileSet) },
"structStyle": func(fields *ast.FieldList) string { return FieldListToStructList(fields, info.FileSet) },
"valuesOnly": func(fields *ast.FieldList) string { return FieldListToNames(fields, info.FileSet) },
+ "encodeErrors": func(structPrefix string, fields *ast.FieldList) string {
+ return FieldListToEncodedErrors(structPrefix, fields, info.FileSet)
+ },
"destruct": func(structPrefix string, fields *ast.FieldList) string {
return FieldListDestruct(structPrefix, fields, info.FileSet)
},