mirror of
https://github.com/juanfont/headscale.git
synced 2026-01-23 02:24:10 +00:00
all: use errors.AsType for type-safe error unwrapping
Replace errors.As with the new errors.AsType generic function
introduced in Go 1.26. This provides compile-time type safety
and approximately 3x better performance by avoiding reflection.
Before:
var target *AppError
if errors.As(err, &target) {
// use target
}
After:
if target, ok := errors.AsType[*AppError](err); ok {
// use target
}
This commit is contained in:
parent
57d9619321
commit
9ab229675d
6 changed files with 20 additions and 29 deletions
|
|
@ -23,8 +23,7 @@ var serveCmd = &cobra.Command{
|
|||
Run: func(cmd *cobra.Command, args []string) {
|
||||
app, err := newHeadscaleServerWithConfig()
|
||||
if err != nil {
|
||||
var squibbleErr squibble.ValidationError
|
||||
if errors.As(err, &squibbleErr) {
|
||||
if squibbleErr, ok := errors.AsType[squibble.ValidationError](err); ok {
|
||||
fmt.Printf("SQLite schema failed to validate:\n")
|
||||
fmt.Println(squibbleErr.Diff)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import (
|
|||
"gorm.io/gorm"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/key"
|
||||
"tailscale.com/types/ptr"
|
||||
)
|
||||
|
||||
type AuthProvider interface {
|
||||
|
|
@ -113,8 +112,7 @@ func (h *Headscale) handleRegister(
|
|||
resp, err := h.handleRegisterWithAuthKey(req, machineKey)
|
||||
if err != nil {
|
||||
// Preserve HTTPError types so they can be handled properly by the HTTP layer
|
||||
var httpErr HTTPError
|
||||
if errors.As(err, &httpErr) {
|
||||
if httpErr, ok := errors.AsType[HTTPError](err); ok {
|
||||
return nil, httpErr
|
||||
}
|
||||
|
||||
|
|
@ -316,7 +314,7 @@ func (h *Headscale) reqToNewRegisterResponse(
|
|||
MachineKey: machineKey,
|
||||
NodeKey: req.NodeKey,
|
||||
Hostinfo: hostinfo,
|
||||
LastSeen: ptr.To(time.Now()),
|
||||
LastSeen: new(time.Now()),
|
||||
},
|
||||
)
|
||||
|
||||
|
|
@ -344,8 +342,7 @@ func (h *Headscale) handleRegisterWithAuthKey(
|
|||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, NewHTTPError(http.StatusUnauthorized, "invalid pre auth key", nil)
|
||||
}
|
||||
var perr types.PAKError
|
||||
if errors.As(err, &perr) {
|
||||
if perr, ok := errors.AsType[types.PAKError](err); ok {
|
||||
return nil, NewHTTPError(http.StatusUnauthorized, perr.Error(), nil)
|
||||
}
|
||||
|
||||
|
|
@ -443,7 +440,7 @@ func (h *Headscale) handleRegisterInteractive(
|
|||
MachineKey: machineKey,
|
||||
NodeKey: req.NodeKey,
|
||||
Hostinfo: hostinfo,
|
||||
LastSeen: ptr.To(time.Now()),
|
||||
LastSeen: new(time.Now()),
|
||||
},
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -36,8 +36,7 @@ const (
|
|||
|
||||
// httpError logs an error and sends an HTTP error response with the given.
|
||||
func httpError(w http.ResponseWriter, err error) {
|
||||
var herr HTTPError
|
||||
if errors.As(err, &herr) {
|
||||
if herr, ok := errors.AsType[HTTPError](err); ok {
|
||||
http.Error(w, herr.Msg, herr.Code)
|
||||
log.Error().Err(herr.Err).Int("code", herr.Code).Msgf("user msg: %s", herr.Msg)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -256,8 +256,7 @@ func (ns *noiseServer) NoiseRegistrationHandler(
|
|||
|
||||
resp, err = ns.headscale.handleRegister(req.Context(), regReq, ns.conn.Peer())
|
||||
if err != nil {
|
||||
var httpErr HTTPError
|
||||
if errors.As(err, &httpErr) {
|
||||
if httpErr, ok := errors.AsType[HTTPError](err); ok {
|
||||
resp = &tailcfg.RegisterResponse{
|
||||
Error: httpErr.Msg,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@ import (
|
|||
"go4.org/netipx"
|
||||
"tailscale.com/net/tsaddr"
|
||||
"tailscale.com/tailcfg"
|
||||
"tailscale.com/types/ptr"
|
||||
"tailscale.com/types/views"
|
||||
"tailscale.com/util/multierr"
|
||||
"tailscale.com/util/slicesx"
|
||||
|
|
@ -656,17 +655,17 @@ func parseAlias(vs string) (Alias, error) {
|
|||
case isWildcard(vs):
|
||||
return Wildcard, nil
|
||||
case isUser(vs):
|
||||
return ptr.To(Username(vs)), nil
|
||||
return new(Username(vs)), nil
|
||||
case isGroup(vs):
|
||||
return ptr.To(Group(vs)), nil
|
||||
return new(Group(vs)), nil
|
||||
case isTag(vs):
|
||||
return ptr.To(Tag(vs)), nil
|
||||
return new(Tag(vs)), nil
|
||||
case isAutoGroup(vs):
|
||||
return ptr.To(AutoGroup(vs)), nil
|
||||
return new(AutoGroup(vs)), nil
|
||||
}
|
||||
|
||||
if isHost(vs) {
|
||||
return ptr.To(Host(vs)), nil
|
||||
return new(Host(vs)), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf(`Invalid alias %q. An alias must be one of the following types:
|
||||
|
|
@ -829,11 +828,11 @@ func (aa AutoApprovers) MarshalJSON() ([]byte, error) {
|
|||
func parseAutoApprover(s string) (AutoApprover, error) {
|
||||
switch {
|
||||
case isUser(s):
|
||||
return ptr.To(Username(s)), nil
|
||||
return new(Username(s)), nil
|
||||
case isGroup(s):
|
||||
return ptr.To(Group(s)), nil
|
||||
return new(Group(s)), nil
|
||||
case isTag(s):
|
||||
return ptr.To(Tag(s)), nil
|
||||
return new(Tag(s)), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf(`Invalid AutoApprover %q. An alias must be one of the following types:
|
||||
|
|
@ -925,11 +924,11 @@ func (o Owners) MarshalJSON() ([]byte, error) {
|
|||
func parseOwner(s string) (Owner, error) {
|
||||
switch {
|
||||
case isUser(s):
|
||||
return ptr.To(Username(s)), nil
|
||||
return new(Username(s)), nil
|
||||
case isGroup(s):
|
||||
return ptr.To(Group(s)), nil
|
||||
return new(Group(s)), nil
|
||||
case isTag(s):
|
||||
return ptr.To(Tag(s)), nil
|
||||
return new(Tag(s)), nil
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf(`Invalid Owner %q. An alias must be one of the following types:
|
||||
|
|
@ -2023,8 +2022,7 @@ func unmarshalPolicy(b []byte) (*Policy, error) {
|
|||
|
||||
ast.Standardize()
|
||||
if err = json.Unmarshal(ast.Pack(), &policy, policyJSONOpts...); err != nil {
|
||||
var serr *json.SemanticError
|
||||
if errors.As(err, &serr) && serr.Err == json.ErrUnknownName {
|
||||
if serr, ok := errors.AsType[*json.SemanticError](err); ok && serr.Err == json.ErrUnknownName {
|
||||
ptr := serr.JSONPointer
|
||||
name := ptr.LastToken()
|
||||
return nil, fmt.Errorf("unknown field %q", name)
|
||||
|
|
|
|||
|
|
@ -110,8 +110,7 @@ func TestCanUsePreAuthKey(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Errorf("expected error but got none")
|
||||
} else {
|
||||
var httpErr PAKError
|
||||
ok := errors.As(err, &httpErr)
|
||||
httpErr, ok := errors.AsType[PAKError](err)
|
||||
if !ok {
|
||||
t.Errorf("expected HTTPError but got %T", err)
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue