@@ -239,6 +239,123 @@ func TestAsValidation(t *testing.T) {
239
239
}
240
240
}
241
241
242
+ func TestAsType (t * testing.T ) {
243
+ var errT errorT
244
+ var errP * fs.PathError
245
+ type timeout interface {
246
+ Timeout () bool
247
+ error
248
+ }
249
+ _ , errF := os .Open ("non-existing" )
250
+ poserErr := & poser {"oh no" , nil }
251
+
252
+ testAsType (t ,
253
+ nil ,
254
+ errP ,
255
+ false ,
256
+ )
257
+ testAsType (t ,
258
+ wrapped {"pitied the fool" , errorT {"T" }},
259
+ errorT {"T" },
260
+ true ,
261
+ )
262
+ testAsType (t ,
263
+ errF ,
264
+ errF ,
265
+ true ,
266
+ )
267
+ testAsType (t ,
268
+ errT ,
269
+ errP ,
270
+ false ,
271
+ )
272
+ testAsType (t ,
273
+ wrapped {"wrapped" , nil },
274
+ errT ,
275
+ false ,
276
+ )
277
+ testAsType (t ,
278
+ & poser {"error" , nil },
279
+ errorT {"poser" },
280
+ true ,
281
+ )
282
+ testAsType (t ,
283
+ & poser {"path" , nil },
284
+ poserPathErr ,
285
+ true ,
286
+ )
287
+ testAsType (t ,
288
+ poserErr ,
289
+ poserErr ,
290
+ true ,
291
+ )
292
+ testAsType (t ,
293
+ errors .New ("err" ),
294
+ timeout (nil ),
295
+ false ,
296
+ )
297
+ testAsType (t ,
298
+ errF ,
299
+ errF .(timeout ),
300
+ true )
301
+ testAsType (t ,
302
+ wrapped {"path error" , errF },
303
+ errF .(timeout ),
304
+ true ,
305
+ )
306
+ testAsType (t ,
307
+ multiErr {},
308
+ errT ,
309
+ false ,
310
+ )
311
+ testAsType (t ,
312
+ multiErr {errors .New ("a" ), errorT {"T" }},
313
+ errorT {"T" },
314
+ true ,
315
+ )
316
+ testAsType (t ,
317
+ multiErr {errorT {"T" }, errors .New ("a" )},
318
+ errorT {"T" },
319
+ true ,
320
+ )
321
+ testAsType (t ,
322
+ multiErr {errorT {"a" }, errorT {"b" }},
323
+ errorT {"a" },
324
+ true ,
325
+ )
326
+ testAsType (t ,
327
+ multiErr {multiErr {errors .New ("a" ), errorT {"a" }}, errorT {"b" }},
328
+ errorT {"a" },
329
+ true ,
330
+ )
331
+ testAsType (t ,
332
+ multiErr {wrapped {"path error" , errF }},
333
+ errF .(timeout ),
334
+ true ,
335
+ )
336
+ testAsType (t ,
337
+ multiErr {nil },
338
+ errT ,
339
+ false ,
340
+ )
341
+ }
342
+
343
+ type compError interface {
344
+ comparable
345
+ error
346
+ }
347
+
348
+ func testAsType [E compError ](t * testing.T , err error , want E , wantOK bool ) {
349
+ t .Helper ()
350
+ name := fmt .Sprintf ("AsType[%T](Errorf(..., %v))" , want , err )
351
+ t .Run (name , func (t * testing.T ) {
352
+ got , gotOK := errors.AsType [E ](err )
353
+ if gotOK != wantOK || got != want {
354
+ t .Fatalf ("got %v, %t; want %v, %t" , got , gotOK , want , wantOK )
355
+ }
356
+ })
357
+ }
358
+
242
359
func BenchmarkIs (b * testing.B ) {
243
360
err1 := errors .New ("1" )
244
361
err2 := multiErr {multiErr {multiErr {err1 , errorT {"a" }}, errorT {"b" }}}
@@ -260,6 +377,15 @@ func BenchmarkAs(b *testing.B) {
260
377
}
261
378
}
262
379
380
+ func BenchmarkAsType (b * testing.B ) {
381
+ err := multiErr {multiErr {multiErr {errors .New ("a" ), errorT {"a" }}, errorT {"b" }}}
382
+ for range b .N {
383
+ if _ , ok := errors.AsType [errorT ](err ); ! ok {
384
+ b .Fatal ("AsType failed" )
385
+ }
386
+ }
387
+ }
388
+
263
389
func TestUnwrap (t * testing.T ) {
264
390
err1 := errors .New ("1" )
265
391
erra := wrapped {"wrap 2" , err1 }
0 commit comments