Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fillmore-labs.com/exp/errors is an experimental Go library providing two enhanced, generic alternatives to errors.As for inspecting error chains with improved ergonomics and type safety.

License

NotificationsYou must be signed in to change notification settings

fillmore-labs/errors-exp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go ReferenceTestCodeQLCoverageGo Report CardLicense

fillmore-labs.com/exp/errors is an experimental Go library that provides four enhanced, generic alternatives toerrors.As for inspecting error chains with improved ergonomics and type safety.

Motivation

In Go, error types can be designed for use as either values or pointers. When inspecting an error chain, a mismatchbetween the type you're looking for (e.g.,MyError) and the type that was actually wrapped (e.g.,*MyError) can leadto subtle, hard-to-find bugs where errors are missed.

Seethis blog post to read more about the issue and theerrortypelinter.

Function Overview

This library provides four functions in two complementary pairs, each building on Go's standarderrors.As:

  • HasError - Ergonomic and type-safe, returns the found error.

  • Has - TheHasError API plus pointer-value mismatch handling.

  • AsError - The classicerrors.As API with generic type safety.

  • As - The classicerrors.As API plus pointer-value mismatch handling.

Featureerrors.AsHasErrorHasAsErrorAs
No target variable needed
Pointer-value mismatch handling
Type safe generics

HasError - Enhanced Ergonomics

HasError Overview

HasError is a generic, type-safe replacement forerrors.As that offers improved ergonomics and readability.

funcHasError[Terror](errerror) (T,bool)

HasError Key Benefits

No Target Variable Needed

Witherrors.As, you must declare a variable beforehand:

varmyErr*MyErroriferrors.As(err,&myErr) {/* ... use myErr */ }

HasError allows you to declare and check in one line:

ifmyErr,ok:=HasError[*MyError](err);ok {/* ... use myErr */ }

Improved Readability

The syntax forerrors.As can sometimes obscure intent, especially when you only need to check for an error's presencewithout using its value. Note howerrors.As requires apointer to a struct literal to check for avalue type:

// This check is valid, but not immediately clear.iferrors.As(err,&x509.UnknownAuthorityError{}) {/* ... */ }

HasError makes the intent explicit and is easier to read:

// The type is clearly specified as a generic parameter.if_,ok:=HasError[x509.UnknownAuthorityError](err);ok {/* ... */ }

Interface Support

HasError works seamlessly with interfaces. To check if an error implements a specific interface:

// Single-line variantife,ok:=HasError[interface {error;Temporary()bool }](err);ok&&e.Temporary() {/* handle temporary error */ }// Or, using a named interface:typetemporaryinterface {error;Temporary()bool }ife,ok:=HasError[temporary](err);ok&&e.Temporary() {/* handle temporary error */ }

When to UseHasError

ChooseHasError when you need:

  • Improved ergonomics compared toerrors.As.
  • Strict type matching, where pointers and values are treated as distinct types.
  • To check if an error in the chainimplements a specific interface.

Has - Pointer-Value Flexibility

Has Overview

Has provides all the benefits ofHasError plus automatic handling of pointer-value type mismatches, preventingsubtle bugs.

funcHas[Terror](errerror) (T,bool)

Has Key Benefits

Automatic Pointer-Value Matching

Has automatically resolves pointer-value mismatches, finding errors thaterrors.As would miss:

// Scenario 1: Looking for a value (MyError), but a pointer (*MyError) was wrapped.err:=&MyError{msg:"oops"}ifmyErr,ok:=Has[MyError](err);ok {/* This matches! */ }// Scenario 2: Looking for a pointer (*MyError), but a value (MyError) was wrapped.err2:=MyError{msg:"oops"}ifmyErr,ok:=Has[*MyError](err2);ok {/* This also matches! */ }

Prevents Common Bugs

This mismatch would silently fail witherrors.As. In the example below,aes.NewCipher returns anaes.KeySizeErrorvalue, but the check incorrectly looks for a pointer (*aes.KeySizeError):

key:= []byte("My kung fu is better than yours")_,err:=aes.NewCipher(key)// With errors.As, this check for a pointer type fails because the// actual error is a value.varkse*aes.KeySizeErroriferrors.As(err,&kse) {// This code is never reached.  }// With Has, the check succeeds because it handles the pointer-value mismatch.ifkse,ok:=Has[*aes.KeySizeError](err);ok {fmt.Printf("Invalid AES key size: %d bytes. Key must be 16, 24, or 32 bytes.\n",*kse)  }

When to UseHas

ChooseHas when you want:

  • The most robust error detection, with all the ergonomic benefits ofHasError.
  • Automatic handling of pointer-value mismatches to prevent subtle bugs caused by inconsistent error wrapping.

Limitations

Unlikeerrors.As, interface types provided toHas orHasError must embed theerror interface.

// This is valid with errors.As:vartempinterface{Temporary()bool }iferrors.As(err,&temp)&&temp.Temporary() {/* handle temporary error */ }// With Has or HasError, the interface must embed `error`:iftemp,ok:=Has[interface {error;Temporary()bool }](err);ok&&temp.Temporary() {/* handle temporary error */ }

Classic API with Enhanced Safety

If you prefer the traditionalerrors.As API that uses target variables, this library provides enhanced versions thatadd the same benefits:

AsError - Type-Safeerrors.As

AsError provides generic type safety to prevent target variable type mismatches:

funcAsError[Terror](errerror,target*T)bool// UsagevarmyErr*MyErrorifAsError(err,&myErr) {// myErr is guaranteed to be the correct type// No risk of type assertion bugs  }

As - Type-Safe with Flexible Matching

As combines type safety with the same pointer-value mismatch handling asHas:

funcAs[Terror](errerror,target*T)bool// UsagevarmyErr*MyErrorifAs(err,&myErr) {// Also handles pointer-value mismatches automatically// Most robust option with familiar API  }

Both functions prevent common type-related bugs while maintaining the familiarerrors.As API that some developersprefer.

Migration Guide

Fromerrors.As toHasError

// BeforevarmyErr*MyErroriferrors.As(err,&myErr) {returnfmt.Errorf("unexpected MyError: %w",myErr) }// AfterifmyErr,ok:=HasError[*MyError](err);ok {returnfmt.Errorf("unexpected MyError: %w",myErr) }

FromHasError toHas

If you suspect pointer-value mismatches are causing issues, replaceHasError withHas.

// If this check sometimes fails unexpectedly:ifmyErr,ok:=HasError[MyError](err);ok {/* ... */ }// Switch to Has for more robust matching:ifmyErr,ok:=Has[MyError](err);ok {/* ... */ }

Further Reading

License

This project is licensed under the Apache License 2.0. See theLICENSE file for details.

About

fillmore-labs.com/exp/errors is an experimental Go library providing two enhanced, generic alternatives to errors.As for inspecting error chains with improved ergonomics and type safety.

Topics

Resources

License

Stars

Watchers

Forks

Languages


[8]ページ先頭

©2009-2025 Movatter.jp