Skip to content

Commit 464c601

Browse files
committed
better error handling in gen package (#134)
1 parent 6327fed commit 464c601

File tree

4 files changed

+96
-58
lines changed

4 files changed

+96
-58
lines changed

gen/generate-components/main.go

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,13 @@ func genGroupDeclarations(name string, fields []datadictionary.MessagePart) (fil
6666
return
6767
}
6868

69-
func genHeader(header *datadictionary.MessageDef) {
69+
func genHeader(header *datadictionary.MessageDef) error {
7070
writer := new(bytes.Buffer)
7171
if err := gen.WritePackage(writer, pkg); err != nil {
72-
panic(err)
72+
return err
7373
}
7474
if err := gen.WriteComponentImports(writer, pkg, header.Parts); err != nil {
75-
panic(err)
75+
return err
7676
}
7777

7878
fileOut := writer.String()
@@ -84,20 +84,20 @@ func genHeader(header *datadictionary.MessageDef) {
8484

8585
writer = new(bytes.Buffer)
8686
if err := gen.WriteFieldSetters(writer, "Header", header.Parts); err != nil {
87-
panic(err)
87+
return err
8888
}
8989
fileOut += writer.String()
9090

91-
gen.WriteFile(path.Join(pkg, "header.go"), fileOut)
91+
return gen.WriteFile(path.Join(pkg, "header.go"), fileOut)
9292
}
9393

94-
func genTrailer(trailer *datadictionary.MessageDef) {
94+
func genTrailer(trailer *datadictionary.MessageDef) error {
9595
writer := new(bytes.Buffer)
9696
if err := gen.WritePackage(writer, pkg); err != nil {
97-
panic(err)
97+
return err
9898
}
9999
if err := gen.WriteComponentImports(writer, pkg, trailer.Parts); err != nil {
100-
panic(err)
100+
return err
101101
}
102102
fileOut := writer.String()
103103

@@ -108,24 +108,24 @@ func genTrailer(trailer *datadictionary.MessageDef) {
108108

109109
writer = new(bytes.Buffer)
110110
if err := gen.WriteFieldSetters(writer, "Trailer", trailer.Parts); err != nil {
111-
panic(err)
111+
return err
112112
}
113113
fileOut += writer.String()
114114

115-
gen.WriteFile(path.Join(pkg, "trailer.go"), fileOut)
115+
return gen.WriteFile(path.Join(pkg, "trailer.go"), fileOut)
116116
}
117117

118-
func genComponent(name string, component *datadictionary.ComponentType) {
118+
func genComponent(name string, component *datadictionary.ComponentType) error {
119119
writer := new(bytes.Buffer)
120120
if err := gen.WritePackage(writer, strings.ToLower(name)); err != nil {
121-
panic(err)
121+
return err
122122
}
123123
if err := gen.WriteComponentImports(writer, pkg, component.Parts()); err != nil {
124-
panic(err)
124+
return err
125125
}
126126

127127
if err := gen.WriteNewComponent(writer, *component); err != nil {
128-
panic(err)
128+
return err
129129
}
130130

131131
fileOut := writer.String()
@@ -136,7 +136,7 @@ func genComponent(name string, component *datadictionary.ComponentType) {
136136
fileOut += "}\n"
137137
fileOut += genComponentSetters(component)
138138

139-
gen.WriteFile(path.Join(pkg, strings.ToLower(name), name+".go"), fileOut)
139+
return gen.WriteFile(path.Join(pkg, strings.ToLower(name), name+".go"), fileOut)
140140
}
141141

142142
func genComponentSetters(component *datadictionary.ComponentType) string {
@@ -173,15 +173,18 @@ func main() {
173173
panic(pkg + "/ is not a directory")
174174
}
175175

176+
var h gen.ErrorHandler
176177
switch pkg {
177178
//uses fixt11 header/trailer
178179
case "fix50", "fix50sp1", "fix50sp2":
179180
default:
180-
genHeader(fixSpec.Header)
181-
genTrailer(fixSpec.Trailer)
181+
h.Handle(genHeader(fixSpec.Header))
182+
h.Handle(genTrailer(fixSpec.Trailer))
182183
}
183184

184185
for name, component := range fixSpec.ComponentTypes {
185-
genComponent(name, component)
186+
h.Handle(genComponent(name, component))
186187
}
188+
189+
os.Exit(h.ReturnCode)
187190
}

gen/generate-fields/main.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func usage() {
2222
os.Exit(2)
2323
}
2424

25-
func genEnums() {
25+
func genEnums() error {
2626
fileOut := "package enum\n"
2727

2828
for _, fieldName := range sortedTags {
@@ -48,10 +48,10 @@ func genEnums() {
4848
fileOut += ")\n"
4949
}
5050

51-
gen.WriteFile("enum/enums.go", fileOut)
51+
return gen.WriteFile("enum/enums.go", fileOut)
5252
}
5353

54-
func genFields() {
54+
func genFields() error {
5555
fileOut := "package field\n"
5656
fileOut += "import(\n"
5757
fileOut += "\"github.com/quickfixgo/quickfix\"\n"
@@ -140,7 +140,7 @@ func genFields() {
140140
goType = "float64"
141141

142142
default:
143-
fmt.Printf("Unknown type '%v' for tag '%v'\n", field.Type, tag)
143+
return fmt.Errorf("Unknown type '%v' for tag '%v'\n", field.Type, tag)
144144
}
145145

146146
fileOut += fmt.Sprintf("//%vField is a %v field\n", field.Name(), field.Type)
@@ -157,10 +157,10 @@ func genFields() {
157157
}
158158
}
159159

160-
gen.WriteFile("field/fields.go", fileOut)
160+
return gen.WriteFile("field/fields.go", fileOut)
161161
}
162162

163-
func genTags() {
163+
func genTags() error {
164164
fileOut := "package tag\n"
165165
fileOut += "import(\"github.com/quickfixgo/quickfix\")\n"
166166

@@ -170,7 +170,7 @@ func genTags() {
170170
}
171171
fileOut += ")\n"
172172

173-
gen.WriteFile("tag/tag_numbers.go", fileOut)
173+
return gen.WriteFile("tag/tag_numbers.go", fileOut)
174174
}
175175

176176
func main() {
@@ -231,7 +231,9 @@ func main() {
231231
}
232232
sort.Strings(sortedTags)
233233

234-
genTags()
235-
genFields()
236-
genEnums()
234+
var h gen.ErrorHandler
235+
h.Handle(genTags())
236+
h.Handle(genFields())
237+
h.Handle(genEnums())
238+
os.Exit(h.ReturnCode)
237239
}

gen/generate-messages/main.go

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,6 @@ func initPackage() {
3434
}
3535
}
3636

37-
func genMessages() {
38-
for _, m := range fixSpec.Messages {
39-
genMessagePkg(m)
40-
}
41-
}
42-
4337
type group struct {
4438
parent string
4539
field *datadictionary.FieldDef
@@ -138,16 +132,16 @@ func Route(router RouteOut) (string,string,quickfix.MessageRoute) {
138132
return fileOut
139133
}
140134

141-
func genMessagePkg(msg *datadictionary.MessageDef) {
135+
func genMessagePkg(msg *datadictionary.MessageDef) error {
142136
pkgName := strings.ToLower(msg.Name)
143137
fileOut := fmt.Sprintf("//Package %v msg type = %v.\n", pkgName, msg.MsgType)
144138

145139
writer := new(bytes.Buffer)
146140
if err := gen.WritePackage(writer, pkgName); err != nil {
147-
panic(err)
141+
return err
148142
}
149143
if err := gen.WriteMessageImports(writer, pkg, msg.Parts); err != nil {
150-
panic(err)
144+
return err
151145
}
152146
fileOut += writer.String()
153147
fileOut += genGroupDeclarations(msg)
@@ -156,7 +150,7 @@ func genMessagePkg(msg *datadictionary.MessageDef) {
156150
fileOut += genMessageSetters(msg)
157151
fileOut += genMessageRoute(msg)
158152

159-
gen.WriteFile(path.Join(pkg, strings.ToLower(msg.Name), msg.Name+".go"), fileOut)
153+
return gen.WriteFile(path.Join(pkg, strings.ToLower(msg.Name), msg.Name+".go"), fileOut)
160154
}
161155

162156
func main() {
@@ -193,5 +187,9 @@ func main() {
193187
panic(pkg + "/ is not a directory")
194188
}
195189

196-
genMessages()
190+
var h gen.ErrorHandler
191+
for _, m := range fixSpec.Messages {
192+
h.Handle(genMessagePkg(m))
193+
}
194+
os.Exit(h.ReturnCode)
197195
}

gen/generate.go

Lines changed: 54 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,38 +12,73 @@ import (
1212

1313
var (
1414
tabWidth = 8
15-
printerMode printer.Mode
15+
printerMode = printer.UseSpaces | printer.TabIndent
1616
)
1717

18-
func init() {
19-
initPrinterMode()
18+
//ParseError indicates generated go source is invalid
19+
type ParseError struct {
20+
path string
21+
err error
2022
}
2123

22-
func initPrinterMode() {
23-
printerMode = printer.UseSpaces | printer.TabIndent
24+
func (e ParseError) Error() string {
25+
return fmt.Sprintf("Error parsing %v: %v", e.path, e.err)
2426
}
2527

26-
func WriteFile(filePath, fileOut string) {
27-
fset := token.NewFileSet()
28-
f, err := parser.ParseFile(fset, "", fileOut, parser.ParseComments)
29-
if err != nil {
30-
fmt.Println("Failed to parse:\n", fileOut)
28+
//ErrorHandler is a convenience struct for interpretting generation Errors
29+
type ErrorHandler struct {
30+
ReturnCode int
31+
}
32+
33+
//Handle interprets the generation error. Proceeds with setting returnCode, or panics depending on error type
34+
func (h *ErrorHandler) Handle(err error) {
35+
switch err := err.(type) {
36+
case nil:
37+
//do nothing
38+
case ParseError:
39+
fmt.Println(err)
40+
h.ReturnCode = 1
41+
default:
3142
panic(err)
3243
}
44+
}
3345

34-
ast.SortImports(fset, f)
35-
36-
//create parentdir if it doesn't exist
46+
func write(filePath string, fset *token.FileSet, f *ast.File) error {
3747
if parentdir := path.Dir(filePath); parentdir != "." {
3848
if err := os.MkdirAll(parentdir, os.ModePerm); err != nil {
39-
panic(err)
49+
return err
4050
}
4151
}
4252

43-
if file, err := os.Create(filePath); err == nil {
44-
defer file.Close()
45-
(&printer.Config{Mode: printerMode, Tabwidth: tabWidth}).Fprint(file, fset, f)
46-
} else {
47-
panic(err)
53+
file, err := os.Create(filePath)
54+
if err != nil {
55+
return err
4856
}
57+
58+
ast.SortImports(fset, f)
59+
err = (&printer.Config{Mode: printerMode, Tabwidth: tabWidth}).Fprint(file, fset, f)
60+
_ = file.Close()
61+
return err
62+
}
63+
64+
//WriteFile parses the generated code in fileOut and writes the code out to filePath.
65+
//Function performs some import clean up and gofmts the code before writing
66+
//Returns ParseError if the generated source is invalid but is written to filePath
67+
func WriteFile(filePath, fileOut string) error {
68+
fset := token.NewFileSet()
69+
f, pErr := parser.ParseFile(fset, "", fileOut, parser.ParseComments)
70+
if f == nil {
71+
return pErr
72+
}
73+
74+
//write out the file regardless of parseFile errors
75+
if err := write(filePath, fset, f); err != nil {
76+
return err
77+
}
78+
79+
if pErr != nil {
80+
return ParseError{path: filePath, err: pErr}
81+
}
82+
83+
return nil
4984
}

0 commit comments

Comments
 (0)