diff --git a/internal/util/util.go b/internal/util/util.go index 50ddc69..f8c5baf 100644 --- a/internal/util/util.go +++ b/internal/util/util.go @@ -6,6 +6,7 @@ package util import ( "cmp" + "fmt" "iter" "reflect" "slices" @@ -73,3 +74,10 @@ func FieldJSONInfo(f reflect.StructField) JSONInfo { } return info } + +// Wrapf wraps *errp with the given formatted message if *errp is not nil. +func Wrapf(errp *error, format string, args ...any) { + if *errp != nil { + *errp = fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), *errp) + } +} diff --git a/jsonschema/json_pointer.go b/jsonschema/json_pointer.go index d7eb4a9..7310b9b 100644 --- a/jsonschema/json_pointer.go +++ b/jsonschema/json_pointer.go @@ -26,6 +26,8 @@ import ( "reflect" "strconv" "strings" + + "github.com/modelcontextprotocol/go-sdk/internal/util" ) var ( @@ -69,7 +71,7 @@ func parseJSONPointer(ptr string) (segments []string, err error) { // This implementation suffices for JSON Schema: pointers are applied only to Schemas, // and refer only to Schemas. func dereferenceJSONPointer(s *Schema, sptr string) (_ *Schema, err error) { - defer wrapf(&err, "JSON Pointer %q", sptr) + defer util.Wrapf(&err, "JSON Pointer %q", sptr) segments, err := parseJSONPointer(sptr) if err != nil { diff --git a/jsonschema/util.go b/jsonschema/util.go index 469ba1a..f884aff 100644 --- a/jsonschema/util.go +++ b/jsonschema/util.go @@ -282,10 +282,3 @@ func assert(cond bool, msg string) { panic("assertion failed: " + msg) } } - -// wrapf wraps *errp with the given formatted message if *errp is not nil. -func wrapf(errp *error, format string, args ...any) { - if *errp != nil { - *errp = fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), *errp) - } -} diff --git a/jsonschema/validate.go b/jsonschema/validate.go index 26b61e1..669e45a 100644 --- a/jsonschema/validate.go +++ b/jsonschema/validate.go @@ -73,7 +73,7 @@ type state struct { // validate validates the reflected value of the instance. func (st *state) validate(instance reflect.Value, schema *Schema, callerAnns *annotations) (err error) { - defer wrapf(&err, "validating %s", schema) + defer util.Wrapf(&err, "validating %s", schema) // Maintain a stack for dynamic schema resolution. st.stack = append(st.stack, schema) // push @@ -607,7 +607,7 @@ func (rs *Resolved) ApplyDefaults(instancep any) error { // Leave this as a potentially recursive helper function, because we'll surely want // to apply defaults on sub-schemas someday. func (st *state) applyDefaults(instancep reflect.Value, schema *Schema) (err error) { - defer wrapf(&err, "applyDefaults: schema %s, instance %v", schema, instancep) + defer util.Wrapf(&err, "applyDefaults: schema %s, instance %v", schema, instancep) instance := instancep.Elem() if instance.Kind() == reflect.Map || instance.Kind() == reflect.Struct { diff --git a/mcp/resource.go b/mcp/resource.go index 8265df3..1fd11ab 100644 --- a/mcp/resource.go +++ b/mcp/resource.go @@ -16,6 +16,7 @@ import ( "strings" "github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2" + "github.com/modelcontextprotocol/go-sdk/internal/util" ) // A ServerResource associates a Resource with its handler. @@ -122,11 +123,7 @@ func fileRoots(rawRoots []*Root) ([]string, error) { // fileRoot returns the absolute path for Root. func fileRoot(root *Root) (_ string, err error) { - defer func() { - if err != nil { - err = fmt.Errorf("root %q: %w", root.URI, err) - } - }() + defer util.Wrapf(&err, "root %q", root.URI) // Convert to absolute file path. rurl, err := url.Parse(root.URI) diff --git a/mcp/server.go b/mcp/server.go index 3521b25..ee86c49 100644 --- a/mcp/server.go +++ b/mcp/server.go @@ -18,6 +18,7 @@ import ( "sync" "github.com/modelcontextprotocol/go-sdk/internal/jsonrpc2" + "github.com/modelcontextprotocol/go-sdk/internal/util" ) const DefaultPageSize = 1000 @@ -296,11 +297,7 @@ func fileResourceHandler(dir string) ResourceHandler { panic(err) } return func(ctx context.Context, ss *ServerSession, params *ReadResourceParams) (_ *ReadResourceResult, err error) { - defer func() { - if err != nil { - err = fmt.Errorf("reading resource %s: %w", params.URI, err) - } - }() + defer util.Wrapf(&err, "reading resource %s", params.URI) // TODO: use a memoizing API here. rootRes, err := ss.ListRoots(ctx, nil)