refactor: replace direct error comparisons with errors.Is
Improves correctness when working with wrapped errors
This commit is contained in:
parent
e8afd31b28
commit
4e68cf5b1e
10 changed files with 21 additions and 15 deletions
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
@ -104,7 +105,7 @@ func (c *LINEChannel) Start(ctx context.Context) error {
|
||||||
"addr": addr,
|
"addr": addr,
|
||||||
"path": path,
|
"path": path,
|
||||||
})
|
})
|
||||||
if err := c.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
if err := c.httpServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||||
logger.ErrorCF("line", "Webhook server error", map[string]interface{}{
|
logger.ErrorCF("line", "Webhook server error", map[string]interface{}{
|
||||||
"error": err.Error(),
|
"error": err.Error(),
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -67,7 +68,7 @@ func (p *CodexCliProvider) Chat(ctx context.Context, messages []Message, tools [
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if ctx.Err() == context.Canceled {
|
if errors.Is(ctx.Err(), context.Canceled) {
|
||||||
return nil, ctx.Err()
|
return nil, ctx.Err()
|
||||||
}
|
}
|
||||||
if stderrStr := stderr.String(); stderrStr != "" {
|
if stderrStr := stderr.String(); stderrStr != "" {
|
||||||
|
|
|
||||||
|
|
@ -91,8 +91,8 @@ func (p *CodexProvider) Chat(ctx context.Context, messages []Message, tools []To
|
||||||
if evt.Type == "response.completed" || evt.Type == "response.failed" || evt.Type == "response.incomplete" {
|
if evt.Type == "response.completed" || evt.Type == "response.failed" || evt.Type == "response.incomplete" {
|
||||||
evtResp := evt.Response
|
evtResp := evt.Response
|
||||||
if evtResp.ID != "" {
|
if evtResp.ID != "" {
|
||||||
copy := evtResp
|
cp := evtResp
|
||||||
resp = ©
|
resp = &cp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package providers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
@ -102,12 +103,12 @@ func ClassifyError(err error, provider, model string) *FailoverError {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context cancellation: user abort, never fallback.
|
// Context cancellation: user abort, never fallback.
|
||||||
if err == context.Canceled {
|
if errors.Is(err, context.Canceled) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context deadline exceeded: treat as timeout, always fallback.
|
// Context deadline exceeded: treat as timeout, always fallback.
|
||||||
if err == context.DeadlineExceeded {
|
if errors.Is(err, context.DeadlineExceeded) {
|
||||||
return &FailoverError{
|
return &FailoverError{
|
||||||
Reason: FailoverTimeout,
|
Reason: FailoverTimeout,
|
||||||
Provider: provider,
|
Provider: provider,
|
||||||
|
|
|
||||||
|
|
@ -293,7 +293,7 @@ func TestFailoverError_ErrorString(t *testing.T) {
|
||||||
func TestFailoverError_Unwrap(t *testing.T) {
|
func TestFailoverError_Unwrap(t *testing.T) {
|
||||||
inner := errors.New("inner error")
|
inner := errors.New("inner error")
|
||||||
fe := &FailoverError{Reason: FailoverTimeout, Wrapped: inner}
|
fe := &FailoverError{Reason: FailoverTimeout, Wrapped: inner}
|
||||||
if fe.Unwrap() != inner {
|
if !errors.Is(inner, fe.Unwrap()) {
|
||||||
t.Error("Unwrap should return wrapped error")
|
t.Error("Unwrap should return wrapped error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package providers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
@ -98,7 +99,7 @@ func (fc *FallbackChain) Execute(
|
||||||
|
|
||||||
for i, candidate := range candidates {
|
for i, candidate := range candidates {
|
||||||
// Check context before each attempt.
|
// Check context before each attempt.
|
||||||
if ctx.Err() == context.Canceled {
|
if errors.Is(ctx.Err(), context.Canceled) {
|
||||||
return nil, context.Canceled
|
return nil, context.Canceled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -130,7 +131,7 @@ func (fc *FallbackChain) Execute(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context cancellation: abort immediately, no fallback.
|
// Context cancellation: abort immediately, no fallback.
|
||||||
if ctx.Err() == context.Canceled {
|
if errors.Is(ctx.Err(), context.Canceled) {
|
||||||
result.Attempts = append(result.Attempts, FallbackAttempt{
|
result.Attempts = append(result.Attempts, FallbackAttempt{
|
||||||
Provider: candidate.Provider,
|
Provider: candidate.Provider,
|
||||||
Model: candidate.Model,
|
Model: candidate.Model,
|
||||||
|
|
@ -204,7 +205,7 @@ func (fc *FallbackChain) ExecuteImage(
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, candidate := range candidates {
|
for i, candidate := range candidates {
|
||||||
if ctx.Err() == context.Canceled {
|
if errors.Is(ctx.Err(), context.Canceled) {
|
||||||
return nil, context.Canceled
|
return nil, context.Canceled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -219,7 +220,7 @@ func (fc *FallbackChain) ExecuteImage(
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if ctx.Err() == context.Canceled {
|
if errors.Is(ctx.Err(), context.Canceled) {
|
||||||
result.Attempts = append(result.Attempts, FallbackAttempt{
|
result.Attempts = append(result.Attempts, FallbackAttempt{
|
||||||
Provider: candidate.Provider,
|
Provider: candidate.Provider,
|
||||||
Model: candidate.Model,
|
Model: candidate.Model,
|
||||||
|
|
|
||||||
|
|
@ -122,7 +122,7 @@ func TestFallback_ContextCanceled(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := fc.Execute(ctx, candidates, run)
|
_, err := fc.Execute(ctx, candidates, run)
|
||||||
if err != context.Canceled {
|
if !errors.Is(err, context.Canceled) {
|
||||||
t.Errorf("expected context.Canceled, got %v", err)
|
t.Errorf("expected context.Canceled, got %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package tools
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
@ -113,7 +114,7 @@ func (t *I2CTool) scan(args map[string]interface{}) *ToolResult {
|
||||||
// Set slave address — EBUSY means a kernel driver owns this address
|
// Set slave address — EBUSY means a kernel driver owns this address
|
||||||
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), i2cSlave, uintptr(addr))
|
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), i2cSlave, uintptr(addr))
|
||||||
if errno != 0 {
|
if errno != 0 {
|
||||||
if errno == syscall.EBUSY {
|
if errors.Is(errno, syscall.EBUSY) {
|
||||||
found = append(found, deviceEntry{
|
found = append(found, deviceEntry{
|
||||||
Address: fmt.Sprintf("0x%02x", addr),
|
Address: fmt.Sprintf("0x%02x", addr),
|
||||||
Status: "busy (in use by kernel driver)",
|
Status: "busy (in use by kernel driver)",
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ func TestMessageTool_Execute_SendFailure(t *testing.T) {
|
||||||
if result.Err == nil {
|
if result.Err == nil {
|
||||||
t.Error("Expected Err to be set")
|
t.Error("Expected Err to be set")
|
||||||
}
|
}
|
||||||
if result.Err != sendErr {
|
if !errors.Is(sendErr, result.Err) {
|
||||||
t.Errorf("Expected Err to be sendErr, got %v", result.Err)
|
t.Errorf("Expected Err to be sendErr, got %v", result.Err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package tools
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
|
@ -188,7 +189,7 @@ func (t *ExecTool) Execute(ctx context.Context, args map[string]interface{}) *To
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if cmdCtx.Err() == context.DeadlineExceeded {
|
if errors.Is(cmdCtx.Err(), context.DeadlineExceeded) {
|
||||||
msg := fmt.Sprintf("Command timed out after %v", t.timeout)
|
msg := fmt.Sprintf("Command timed out after %v", t.timeout)
|
||||||
return &ToolResult{
|
return &ToolResult{
|
||||||
ForLLM: msg,
|
ForLLM: msg,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue