Files
amcs/internal/tools/common.go
Hein f41c512f36 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.
2026-03-31 15:10:07 +02:00

146 lines
3.0 KiB
Go

package tools
import (
"encoding/json"
"fmt"
"strings"
"git.warky.dev/wdevs/amcs/internal/config"
"git.warky.dev/wdevs/amcs/internal/mcperrors"
"github.com/modelcontextprotocol/go-sdk/jsonrpc"
)
func normalizeLimit(limit int, cfg config.SearchConfig) int {
if limit <= 0 {
return cfg.DefaultLimit
}
if limit > cfg.MaxLimit {
return cfg.MaxLimit
}
return limit
}
func normalizeThreshold(value float64, fallback float64) float64 {
if value <= 0 {
return fallback
}
if value > 1 {
return 1
}
return value
}
const (
codeSessionRequired = mcperrors.CodeSessionRequired
codeProjectRequired = mcperrors.CodeProjectRequired
codeProjectNotFound = mcperrors.CodeProjectNotFound
codeInvalidID = mcperrors.CodeInvalidID
codeEntityNotFound = mcperrors.CodeEntityNotFound
)
type mcpErrorData = mcperrors.Data
func newMCPError(code int64, message string, data mcpErrorData) error {
rpcErr := &jsonrpc.Error{
Code: code,
Message: message,
}
payload, err := json.Marshal(data)
if err != nil {
return fmt.Errorf("marshal mcp error data: %w", err)
}
rpcErr.Data = payload
return rpcErr
}
func errInvalidInput(message string) error {
return newMCPError(
jsonrpc.CodeInvalidParams,
"invalid input: "+message,
mcpErrorData{
Type: mcperrors.TypeInvalidInput,
},
)
}
func errRequiredField(field string) error {
return newMCPError(
jsonrpc.CodeInvalidParams,
field+" is required",
mcpErrorData{
Type: mcperrors.TypeInvalidInput,
Field: field,
Detail: "required",
Hint: "provide " + field,
},
)
}
func errInvalidField(field string, message string, hint string) error {
return newMCPError(
jsonrpc.CodeInvalidParams,
message,
mcpErrorData{
Type: mcperrors.TypeInvalidInput,
Field: field,
Detail: "invalid",
Hint: hint,
},
)
}
func errOneOfRequired(fields ...string) error {
return newMCPError(
jsonrpc.CodeInvalidParams,
joinFields(fields)+" is required",
mcpErrorData{
Type: mcperrors.TypeInvalidInput,
Fields: fields,
Detail: "one_of_required",
Hint: "provide one of: " + strings.Join(fields, ", "),
},
)
}
func errMutuallyExclusiveFields(fields ...string) error {
return newMCPError(
jsonrpc.CodeInvalidParams,
"provide "+joinFields(fields)+", not both",
mcpErrorData{
Type: mcperrors.TypeInvalidInput,
Fields: fields,
Detail: "mutually_exclusive",
Hint: "provide only one of: " + strings.Join(fields, ", "),
},
)
}
func errEntityNotFound(entity string, field string, value string) error {
return newMCPError(
codeEntityNotFound,
entity+" not found",
mcpErrorData{
Type: mcperrors.TypeEntityNotFound,
Entity: entity,
Field: field,
Value: value,
Detail: "not_found",
},
)
}
func joinFields(fields []string) string {
switch len(fields) {
case 0:
return "field"
case 1:
return fields[0]
case 2:
return fields[0] + " or " + fields[1]
default:
return strings.Join(fields[:len(fields)-1], ", ") + ", or " + fields[len(fields)-1]
}
}