test(tools): add unit tests for error handling functions

* Implement tests for error functions like errRequiredField, errInvalidField, and errEntityNotFound.
* Ensure proper metadata is returned for various error scenarios.
* Validate error handling in CRM, Files, and other tools.
* Introduce tests for parsing stored file IDs and UUIDs.
* Enhance coverage for helper functions related to project resolution and session management.
This commit is contained in:
Hein
2026-03-31 15:10:07 +02:00
parent acd780ac9c
commit f41c512f36
54 changed files with 1937 additions and 365 deletions

View File

@@ -9,22 +9,41 @@ import (
"github.com/jackc/pgx/v5"
"github.com/modelcontextprotocol/go-sdk/mcp"
"git.warky.dev/wdevs/amcs/internal/mcperrors"
"git.warky.dev/wdevs/amcs/internal/session"
"git.warky.dev/wdevs/amcs/internal/store"
thoughttypes "git.warky.dev/wdevs/amcs/internal/types"
)
func parseUUID(id string) (uuid.UUID, error) {
parsed, err := uuid.Parse(strings.TrimSpace(id))
trimmed := strings.TrimSpace(id)
parsed, err := uuid.Parse(trimmed)
if err != nil {
return uuid.Nil, fmt.Errorf("invalid id %q: %w", id, err)
return uuid.Nil, newMCPError(
codeInvalidID,
fmt.Sprintf("invalid id %q", id),
mcpErrorData{
Type: mcperrors.TypeInvalidID,
Field: "id",
Value: trimmed,
Detail: err.Error(),
Hint: "pass a valid UUID",
},
)
}
return parsed, nil
}
func sessionID(req *mcp.CallToolRequest) (string, error) {
if req == nil || req.Session == nil || req.Session.ID() == "" {
return "", fmt.Errorf("tool requires an MCP session")
return "", newMCPError(
codeSessionRequired,
"tool requires an MCP session; use a stateful MCP client for session-scoped operations",
mcpErrorData{
Type: mcperrors.TypeSessionRequired,
Hint: "use a stateful MCP client for session-scoped operations",
},
)
}
return req.Session.ID(), nil
}
@@ -45,7 +64,15 @@ func resolveProject(ctx context.Context, db *store.DB, sessions *session.ActiveP
if projectRef == "" {
if required {
return nil, fmt.Errorf("project is required")
return nil, newMCPError(
codeProjectRequired,
"project is required; pass project explicitly or call set_active_project in this MCP session first",
mcpErrorData{
Type: mcperrors.TypeProjectRequired,
Field: "project",
Hint: "pass project explicitly or call set_active_project in this MCP session first",
},
)
}
return nil, nil
}
@@ -53,7 +80,15 @@ func resolveProject(ctx context.Context, db *store.DB, sessions *session.ActiveP
project, err := db.GetProject(ctx, projectRef)
if err != nil {
if err == pgx.ErrNoRows {
return nil, fmt.Errorf("project %q not found", projectRef)
return nil, newMCPError(
codeProjectNotFound,
fmt.Sprintf("project %q not found", projectRef),
mcpErrorData{
Type: mcperrors.TypeProjectNotFound,
Field: "project",
Project: projectRef,
},
)
}
return nil, err
}