Skip to content

Commit 1e24be9

Browse files
authored
Merge pull request #701 from peterstace/refactor_catch_fn
Make catch generic to improve call site ergonomics
2 parents f861271 + dc0186e commit 1e24be9

File tree

6 files changed

+36
-48
lines changed

6 files changed

+36
-48
lines changed

geom/alg_buffer.go

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,17 @@ func Buffer(g Geometry, distance float64, opts ...BufferOption) (Geometry, error
2727
opt(params)
2828
}
2929

30-
var result Geometry
31-
err := catch(func() error {
30+
return catch(func() (Geometry, error) {
3231
wkbReader := jts.Io_NewWKBReader()
3332
jtsG, err := wkbReader.ReadBytes(g.AsBinary())
3433
if err != nil {
35-
return wrap(err, "converting geometry to JTS")
34+
return Geometry{}, wrap(err, "converting geometry to JTS")
3635
}
3736
jtsResult := jts.OperationBuffer_BufferOp_BufferOpWithParams(jtsG, distance, params)
3837
wkbWriter := jts.Io_NewWKBWriter()
39-
result, err = UnmarshalWKB(wkbWriter.Write(jtsResult), NoValidate{})
40-
return wrap(err, "converting JTS buffer result to simplefeatures")
38+
result, err := UnmarshalWKB(wkbWriter.Write(jtsResult), NoValidate{})
39+
return result, wrap(err, "converting JTS buffer result to simplefeatures")
4140
})
42-
return result, err
4341
}
4442

4543
// BufferOption allows the behaviour of the [Buffer] operation to be modified.

geom/alg_overlay.go

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -221,23 +221,21 @@ func gcAwareDifference(a, b Geometry) (Geometry, error) {
221221

222222
// jtsOverlayOp invokes the JTS port's overlay operation with the given opCode.
223223
func jtsOverlayOp(a, b Geometry, opCode int) (Geometry, error) {
224-
var result Geometry
225-
err := catch(func() error {
224+
return catch(func() (Geometry, error) {
226225
wkbReader := jts.Io_NewWKBReader()
227226
jtsA, err := wkbReader.ReadBytes(a.AsBinary())
228227
if err != nil {
229-
return wrap(err, "converting geometry A to JTS")
228+
return Geometry{}, wrap(err, "converting geometry A to JTS")
230229
}
231230
jtsB, err := wkbReader.ReadBytes(b.AsBinary())
232231
if err != nil {
233-
return wrap(err, "converting geometry B to JTS")
232+
return Geometry{}, wrap(err, "converting geometry B to JTS")
234233
}
235234
jtsResult := jts.OperationOverlayng_OverlayNGRobust_Overlay(jtsA, jtsB, opCode)
236235
wkbWriter := jts.Io_NewWKBWriter()
237-
result, err = UnmarshalWKB(wkbWriter.Write(jtsResult), NoValidate{})
238-
return wrap(err, "converting JTS overlay result to simplefeatures")
236+
result, err := UnmarshalWKB(wkbWriter.Write(jtsResult), NoValidate{})
237+
return result, wrap(err, "converting JTS overlay result to simplefeatures")
239238
})
240-
return result, err
241239
}
242240

243241
// SymmetricDifference returns a geometry that represents the parts of geometry
@@ -288,17 +286,15 @@ func UnionMany(gs []Geometry) (Geometry, error) {
288286

289287
// jtsUnaryUnion invokes the JTS port's unary union operation.
290288
func jtsUnaryUnion(g Geometry) (Geometry, error) {
291-
var result Geometry
292-
err := catch(func() error {
289+
return catch(func() (Geometry, error) {
293290
wkbReader := jts.Io_NewWKBReader()
294291
jtsG, err := wkbReader.ReadBytes(g.AsBinary())
295292
if err != nil {
296-
return wrap(err, "converting geometry to JTS")
293+
return Geometry{}, wrap(err, "converting geometry to JTS")
297294
}
298295
jtsResult := jts.OperationOverlayng_OverlayNGRobust_Union(jtsG)
299296
wkbWriter := jts.Io_NewWKBWriter()
300-
result, err = UnmarshalWKB(wkbWriter.Write(jtsResult), NoValidate{})
301-
return wrap(err, "converting JTS union result to simplefeatures")
297+
result, err := UnmarshalWKB(wkbWriter.Write(jtsResult), NoValidate{})
298+
return result, wrap(err, "converting JTS union result to simplefeatures")
302299
})
303-
return result, err
304300
}

geom/alg_prepared.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,15 @@ type PreparedGeometry struct {
1515

1616
// Prepare preprocesses a geometry for efficient repeated predicate evaluation.
1717
func Prepare(g Geometry) (PreparedGeometry, error) {
18-
var pg PreparedGeometry
19-
err := catch(func() error {
18+
return catch(func() (PreparedGeometry, error) {
2019
jtsG, err := toJTS(g)
2120
if err != nil {
22-
return err
21+
return PreparedGeometry{}, err
2322
}
24-
pg.prep = jts.GeomPrep_PreparedGeometryFactory_Prepare(jtsG)
25-
return nil
23+
return PreparedGeometry{
24+
prep: jts.GeomPrep_PreparedGeometryFactory_Prepare(jtsG),
25+
}, nil
2626
})
27-
return pg, err
2827
}
2928

3029
func toJTS(g Geometry) (*jts.Geom_Geometry, error) {
@@ -36,16 +35,13 @@ func toJTS(g Geometry) (*jts.Geom_Geometry, error) {
3635
}
3736

3837
func (p PreparedGeometry) eval(g Geometry, pred func(*jts.Geom_Geometry) bool) (bool, error) {
39-
var result bool
40-
err := catch(func() error {
38+
return catch(func() (bool, error) {
4139
jtsG, err := toJTS(g)
4240
if err != nil {
43-
return err
41+
return false, err
4442
}
45-
result = pred(jtsG)
46-
return nil
43+
return pred(jtsG), nil
4744
})
48-
return result, err
4945
}
5046

5147
// Intersects reports whether the prepared geometry intersects g.

geom/alg_relate.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,22 +64,20 @@ func relateWithEmptyInput(a, b Geometry) string {
6464

6565
// jtsRelateNG invokes the JTS port's RelateNG operation.
6666
func jtsRelateNG(a, b Geometry) (string, error) {
67-
var result string
68-
err := catch(func() error {
67+
return catch(func() (string, error) {
6968
wkbReader := jts.Io_NewWKBReader()
7069
jtsA, err := wkbReader.ReadBytes(a.AsBinary())
7170
if err != nil {
72-
return wrap(err, "converting geometry A to JTS")
71+
return "", wrap(err, "converting geometry A to JTS")
7372
}
7473
jtsB, err := wkbReader.ReadBytes(b.AsBinary())
7574
if err != nil {
76-
return wrap(err, "converting geometry B to JTS")
75+
return "", wrap(err, "converting geometry B to JTS")
7776
}
7877
im := jts.OperationRelateng_RelateNG_RelateMatrix(jtsA, jtsB)
79-
result = im.String()
80-
return validateIntersectionMatrix(result)
78+
result := im.String()
79+
return result, validateIntersectionMatrix(result)
8180
})
82-
return result, err
8381
}
8482

8583
func relateMatchesAnyPattern(a, b Geometry, patterns ...string) (bool, error) {

geom/util.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ func arbitraryControlPoint(g Geometry) Point {
141141
}
142142
}
143143

144-
func catch(fn func() error) (err error) {
144+
func catch[T any](fn func() (T, error)) (result T, err error) { //nolint:ireturn
145145
// In Go 1.21+, panic(nil) causes recover() to return a *runtime.PanicNilError
146146
// rather than nil. In earlier versions, recover() returns nil for panic(nil),
147147
// making it indistinguishable from "no panic". We emulate the Go 1.21+ behavior
@@ -158,7 +158,7 @@ func catch(fn func() error) (err error) {
158158
}
159159
}
160160
}()
161-
err = fn()
161+
result, err = fn()
162162
panicked = false
163163
return
164164
}

geom/util_internal_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,42 +74,42 @@ func BenchmarkMathMax(b *testing.B) {
7474
func TestCatch(t *testing.T) {
7575
for _, tc := range []struct {
7676
name string
77-
fn func() error
77+
fn func() (struct{}, error)
7878
wantErr string
7979
}{
8080
{
8181
name: "function returns nil",
82-
fn: func() error { return nil },
82+
fn: func() (struct{}, error) { return struct{}{}, nil },
8383
wantErr: "",
8484
},
8585
{
8686
name: "function returns error",
87-
fn: func() error { return errors.New("test error") },
87+
fn: func() (struct{}, error) { return struct{}{}, errors.New("test error") },
8888
wantErr: "test error",
8989
},
9090
{
9191
name: "function panics with string",
92-
fn: func() error { panic("something went wrong") },
92+
fn: func() (struct{}, error) { panic("something went wrong") },
9393
wantErr: "panic: something went wrong",
9494
},
9595
{
9696
name: "function panics with error",
97-
fn: func() error { panic(errors.New("panic error")) },
97+
fn: func() (struct{}, error) { panic(errors.New("panic error")) },
9898
wantErr: "panic: panic error",
9999
},
100100
{
101101
name: "function panics with int",
102-
fn: func() error { panic(42) },
102+
fn: func() (struct{}, error) { panic(42) },
103103
wantErr: "panic: 42",
104104
},
105105
{
106106
name: "function panics with nil",
107-
fn: func() error { panic(nil) },
107+
fn: func() (struct{}, error) { panic(nil) },
108108
wantErr: "panic: panic called with nil argument",
109109
},
110110
} {
111111
t.Run(tc.name, func(t *testing.T) {
112-
err := catch(tc.fn)
112+
_, err := catch(tc.fn)
113113
if tc.wantErr == "" {
114114
if err != nil {
115115
t.Errorf("got %v, want nil", err)

0 commit comments

Comments
 (0)