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:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user