this repo has no description
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Refactor JSON error handling to use Util.json_error helper

- Update all instances of direct 'raise (Json.Of_json' to use the centralized helper
- Use consistent error message formatting with the helper in both mcp.ml and mcp_rpc.ml
- Ensure all JSON parsing errors include the JSON object in the error message
- Maintain standard naming patterns for all error messages

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

+143 -131
+70 -66
lib/mcp.ml
··· 2 2 3 3 (* Utility functions for JSON parsing *) 4 4 module Util = struct 5 + (* Helper to raise a Json.Of_json exception with formatted message *) 6 + let json_error fmt json = 7 + Printf.ksprintf (fun msg -> raise (Json.Of_json (msg, json))) fmt 8 + 5 9 (* Extract a string field from JSON object or raise an error *) 6 10 let get_string_field fields name json = 7 11 match List.assoc_opt name fields with 8 12 | Some (`String s) -> s 9 - | _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json)) 13 + | _ -> json_error "Missing or invalid '%s' field" json name 10 14 11 15 (* Extract an optional string field from JSON object *) 12 16 let get_optional_string_field fields name = 13 17 List.assoc_opt name fields |> Option.map (function 14 18 | `String s -> s 15 - | j -> raise (Json.Of_json (Printf.sprintf "Expected string for %s" name, j)) 19 + | j -> json_error "Expected string for %s" j name 16 20 ) 17 21 18 22 (* Extract an int field from JSON object or raise an error *) 19 23 let get_int_field fields name json = 20 24 match List.assoc_opt name fields with 21 25 | Some (`Int i) -> i 22 - | _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json)) 26 + | _ -> json_error "Missing or invalid '%s' field" json name 23 27 24 28 (* Extract a float field from JSON object or raise an error *) 25 29 let get_float_field fields name json = 26 30 match List.assoc_opt name fields with 27 31 | Some (`Float f) -> f 28 - | _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json)) 32 + | _ -> json_error "Missing or invalid '%s' field" json name 29 33 30 34 (* Extract a boolean field from JSON object or raise an error *) 31 35 let get_bool_field fields name json = 32 36 match List.assoc_opt name fields with 33 37 | Some (`Bool b) -> b 34 - | _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json)) 38 + | _ -> json_error "Missing or invalid '%s' field" json name 35 39 36 40 (* Extract an object field from JSON object or raise an error *) 37 41 let get_object_field fields name json = 38 42 match List.assoc_opt name fields with 39 43 | Some (`Assoc obj) -> obj 40 - | _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json)) 44 + | _ -> json_error "Missing or invalid '%s' field" json name 41 45 42 46 (* Extract a list field from JSON object or raise an error *) 43 47 let get_list_field fields name json = 44 48 match List.assoc_opt name fields with 45 49 | Some (`List items) -> items 46 - | _ -> raise (Json.Of_json (Printf.sprintf "Missing or invalid '%s' field" name, json)) 50 + | _ -> json_error "Missing or invalid '%s' field" json name 47 51 48 52 (* Verify a specific string value in a field *) 49 53 let verify_string_field fields name expected_value json = 50 54 match List.assoc_opt name fields with 51 55 | Some (`String s) when s = expected_value -> () 52 - | _ -> raise (Json.Of_json (Printf.sprintf "Field '%s' missing or not equal to '%s'" name expected_value, json)) 56 + | _ -> json_error "Field '%s' missing or not equal to '%s'" json name expected_value 53 57 end 54 58 55 59 (* Error codes for JSON-RPC *) ··· 166 170 let of_string = function 167 171 | "user" -> `User 168 172 | "assistant" -> `Assistant 169 - | s -> raise (Json.Of_json ("Unknown role: " ^ s, `String s)) 173 + | s -> Util.json_error "Unknown role: %s" (`String s) s 170 174 171 175 let yojson_of_t t = `String (to_string t) 172 176 let t_of_yojson = function 173 177 | `String s -> of_string s 174 - | j -> raise (Json.Of_json ("Expected string for Role", j)) 178 + | j -> Util.json_error "Expected string for Role" j 175 179 end 176 180 177 181 module ProgressToken = struct ··· 188 192 let yojson_of_t t = `String t 189 193 let t_of_yojson = function 190 194 | `String s -> s 191 - | j -> raise (Json.Of_json ("Expected string for Cursor", j)) 195 + | j -> Util.json_error "Expected string for Cursor" j 192 196 end 193 197 194 198 (* Annotations *) ··· 218 222 | `Assoc fields -> 219 223 let audience = List.assoc_opt "audience" fields |> Option.map (function 220 224 | `List items -> List.map Role.t_of_yojson items 221 - | j -> raise (Json.Of_json ("Expected list for audience", j)) 225 + | j -> Util.json_error "Expected list for audience" j 222 226 ) in 223 227 let priority = List.assoc_opt "priority" fields |> Option.map (function 224 228 | `Float f -> f 225 - | j -> raise (Json.Of_json ("Expected float for priority", j)) 229 + | j -> Util.json_error "Expected float for priority" j 226 230 ) in 227 231 { audience; priority } 228 - | j -> raise (Json.Of_json ("Expected object for annotation", j)) 232 + | j -> Util.json_error "Expected object for annotation" j 229 233 230 234 let yojson_of_t { annotations } = 231 235 match annotations with ··· 236 240 | `Assoc fields -> 237 241 let annotations = List.assoc_opt "annotations" fields |> Option.map annotation_of_yojson in 238 242 { annotations } 239 - | j -> raise (Json.Of_json ("Expected object for Annotated", j)) 243 + | j -> Util.json_error "Expected object for Annotated" j 240 244 end 241 245 242 246 (* Content types *) ··· 264 268 Util.verify_string_field fields "type" "text" json; 265 269 let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in 266 270 { text; annotations } 267 - | j -> raise (Json.Of_json ("Expected object for TextContent", j)) 271 + | j -> Util.json_error "Expected object for TextContent" j 268 272 end 269 273 270 274 module ImageContent = struct ··· 293 297 Util.verify_string_field fields "type" "image" json; 294 298 let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in 295 299 { data; mime_type; annotations } 296 - | j -> raise (Json.Of_json ("Expected object for ImageContent", j)) 300 + | j -> Util.json_error "Expected object for ImageContent" j 297 301 end 298 302 299 303 module AudioContent = struct ··· 322 326 Util.verify_string_field fields "type" "audio" json; 323 327 let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in 324 328 { data; mime_type; annotations } 325 - | j -> raise (Json.Of_json ("Expected object for AudioContent", j)) 329 + | j -> Util.json_error "Expected object for AudioContent" j 326 330 end 327 331 328 332 module ResourceContents = struct ··· 346 350 let uri = Util.get_string_field fields "uri" json in 347 351 let mime_type = Util.get_optional_string_field fields "mimeType" in 348 352 { uri; mime_type } 349 - | j -> raise (Json.Of_json ("Expected object for ResourceContents", j)) 353 + | j -> Util.json_error "Expected object for ResourceContents" j 350 354 end 351 355 352 356 module TextResourceContents = struct ··· 373 377 let text = Util.get_string_field fields "text" json in 374 378 let mime_type = Util.get_optional_string_field fields "mimeType" in 375 379 { uri; text; mime_type } 376 - | j -> raise (Json.Of_json ("Expected object for TextResourceContents", j)) 380 + | j -> Util.json_error "Expected object for TextResourceContents" j 377 381 end 378 382 379 383 module BlobResourceContents = struct ··· 400 404 let blob = Util.get_string_field fields "blob" json in 401 405 let mime_type = Util.get_optional_string_field fields "mimeType" in 402 406 { uri; blob; mime_type } 403 - | j -> raise (Json.Of_json ("Expected object for BlobResourceContents", j)) 407 + | j -> Util.json_error "Expected object for BlobResourceContents" j 404 408 end 405 409 406 410 module EmbeddedResource = struct ··· 429 433 Util.verify_string_field fields "type" "resource" json; 430 434 let resource_fields = match List.assoc_opt "resource" fields with 431 435 | Some (`Assoc res_fields) -> res_fields 432 - | _ -> raise (Json.Of_json ("Missing or invalid 'resource' field", json)) 436 + | _ -> Util.json_error "Missing or invalid 'resource' field" json 433 437 in 434 438 let resource = 435 439 if List.mem_assoc "text" resource_fields then ··· 437 441 else if List.mem_assoc "blob" resource_fields then 438 442 `Blob (BlobResourceContents.t_of_yojson (`Assoc resource_fields)) 439 443 else 440 - raise (Json.Of_json ("Invalid resource content", `Assoc resource_fields)) 444 + Util.json_error "Invalid resource content" (`Assoc resource_fields) 441 445 in 442 446 let annotations = List.assoc_opt "annotations" fields |> Option.map Annotated.annotation_of_yojson in 443 447 { resource; annotations } 444 - | j -> raise (Json.Of_json ("Expected object for EmbeddedResource", j)) 448 + | j -> Util.json_error "Expected object for EmbeddedResource" j 445 449 end 446 450 447 451 type content = ··· 457 461 | Resource r -> EmbeddedResource.yojson_of_t r 458 462 459 463 let content_of_yojson = function 460 - | `Assoc fields -> 464 + | `Assoc fields as json -> 461 465 (match List.assoc_opt "type" fields with 462 - | Some (`String "text") -> Text (TextContent.t_of_yojson (`Assoc fields)) 463 - | Some (`String "image") -> Image (ImageContent.t_of_yojson (`Assoc fields)) 464 - | Some (`String "audio") -> Audio (AudioContent.t_of_yojson (`Assoc fields)) 465 - | Some (`String "resource") -> Resource (EmbeddedResource.t_of_yojson (`Assoc fields)) 466 - | _ -> raise (Json.Of_json ("Invalid or missing content type", `Assoc fields))) 467 - | j -> raise (Json.Of_json ("Expected object for content", j)) 466 + | Some (`String "text") -> Text (TextContent.t_of_yojson json) 467 + | Some (`String "image") -> Image (ImageContent.t_of_yojson json) 468 + | Some (`String "audio") -> Audio (AudioContent.t_of_yojson json) 469 + | Some (`String "resource") -> Resource (EmbeddedResource.t_of_yojson json) 470 + | _ -> Util.json_error "Invalid or missing content type" json) 471 + | j -> Util.json_error "Expected object for content" j 468 472 469 473 (* Message types *) 470 474 ··· 484 488 | `Assoc fields as json -> 485 489 let role = match List.assoc_opt "role" fields with 486 490 | Some json -> Role.t_of_yojson json 487 - | None -> raise (Json.Of_json ("Missing role field", json)) 491 + | None -> Util.json_error "Missing role field" json 488 492 in 489 493 let content = match List.assoc_opt "content" fields with 490 494 | Some json -> content_of_yojson json 491 - | None -> raise (Json.Of_json ("Missing content field", json)) 495 + | None -> Util.json_error "Missing content field" json 492 496 in 493 497 { role; content } 494 - | j -> raise (Json.Of_json ("Expected object for PromptMessage", j)) 498 + | j -> Util.json_error "Expected object for PromptMessage" j 495 499 end 496 500 497 501 module SamplingMessage = struct ··· 515 519 | `Assoc fields as json -> 516 520 let role = match List.assoc_opt "role" fields with 517 521 | Some json -> Role.t_of_yojson json 518 - | None -> raise (Json.Of_json ("Missing role field", json)) 522 + | None -> Util.json_error "Missing role field" json 519 523 in 520 524 let content_obj = match List.assoc_opt "content" fields with 521 525 | Some (`Assoc content_fields) -> content_fields 522 - | _ -> raise (Json.Of_json ("Missing or invalid content field", json)) 526 + | _ -> Util.json_error "Missing or invalid content field" json 523 527 in 524 528 let content_type = match List.assoc_opt "type" content_obj with 525 529 | Some (`String ty) -> ty 526 - | _ -> raise (Json.Of_json ("Missing or invalid content type", `Assoc content_obj)) 530 + | _ -> Util.json_error "Missing or invalid content type" (`Assoc content_obj) 527 531 in 528 532 let content = 529 533 match content_type with 530 534 | "text" -> `Text (TextContent.t_of_yojson (`Assoc content_obj)) 531 535 | "image" -> `Image (ImageContent.t_of_yojson (`Assoc content_obj)) 532 536 | "audio" -> `Audio (AudioContent.t_of_yojson (`Assoc content_obj)) 533 - | _ -> raise (Json.Of_json (Printf.sprintf "Invalid content type: %s" content_type, `Assoc content_obj)) 537 + | _ -> Util.json_error "Invalid content type: %s" (`Assoc content_obj) content_type 534 538 in 535 539 { role; content } 536 - | j -> raise (Json.Of_json ("Expected object for SamplingMessage", j)) 540 + | j -> Util.json_error "Expected object for SamplingMessage" j 537 541 end 538 542 539 543 (* Implementation info *) ··· 555 559 let name = Util.get_string_field fields "name" json in 556 560 let version = Util.get_string_field fields "version" json in 557 561 { name; version } 558 - | j -> raise (Json.Of_json ("Expected object for Implementation", j)) 562 + | j -> Util.json_error "Expected object for Implementation" j 559 563 end 560 564 561 565 (* JSONRPC Message types *) ··· 659 663 let meth = match List.assoc_opt "method" fields with 660 664 | Some (`String s) -> 661 665 (try Method.of_string s 662 - with Failure msg -> raise (Json.Of_json (msg, `String s))) 663 - | _ -> raise (Json.Of_json ("Missing or invalid 'method' field", `Assoc fields)) 666 + with Failure msg -> Util.json_error "%s" (`String s) msg) 667 + | _ -> Util.json_error "Missing or invalid 'method' field" (`Assoc fields) 664 668 in 665 669 let params = List.assoc_opt "params" fields in 666 670 { meth; params } 667 - | j -> raise (Json.Of_json ("Expected object for notification", j)) 671 + | j -> Util.json_error "Expected object for notification" j 668 672 669 673 let request_of_yojson = function 670 674 | `Assoc fields -> 671 675 let id = match List.assoc_opt "id" fields with 672 676 | Some id_json -> Id.t_of_yojson id_json 673 - | _ -> raise (Json.Of_json ("Missing or invalid 'id' field", `Assoc fields)) 677 + | _ -> Util.json_error "Missing or invalid 'id' field" (`Assoc fields) 674 678 in 675 679 let meth = match List.assoc_opt "method" fields with 676 680 | Some (`String s) -> 677 681 (try Method.of_string s 678 - with Failure msg -> raise (Json.Of_json (msg, `String s))) 679 - | _ -> raise (Json.Of_json ("Missing or invalid 'method' field", `Assoc fields)) 682 + with Failure msg -> Util.json_error "%s" (`String s) msg) 683 + | _ -> Util.json_error "Missing or invalid 'method' field" (`Assoc fields) 680 684 in 681 685 let params = List.assoc_opt "params" fields in 682 686 let progress_token = ··· 691 695 | _ -> None 692 696 in 693 697 { id; meth; params; progress_token } 694 - | j -> raise (Json.Of_json ("Expected object for request", j)) 698 + | j -> Util.json_error "Expected object for request" j 695 699 696 700 let response_of_yojson = function 697 701 | `Assoc fields -> 698 702 let id = match List.assoc_opt "id" fields with 699 703 | Some id_json -> Id.t_of_yojson id_json 700 - | _ -> raise (Json.Of_json ("Missing or invalid 'id' field", `Assoc fields)) 704 + | _ -> Util.json_error "Missing or invalid 'id' field" (`Assoc fields) 701 705 in 702 706 let result = match List.assoc_opt "result" fields with 703 707 | Some result -> result 704 - | _ -> raise (Json.Of_json ("Missing 'result' field", `Assoc fields)) 708 + | _ -> Util.json_error "Missing 'result' field" (`Assoc fields) 705 709 in 706 710 { id; result } 707 - | j -> raise (Json.Of_json ("Expected object for response", j)) 711 + | j -> Util.json_error "Expected object for response" j 708 712 709 713 let error_of_yojson = function 710 - | `Assoc fields -> 714 + | `Assoc fields as json -> 711 715 let id = match List.assoc_opt "id" fields with 712 716 | Some id_json -> Id.t_of_yojson id_json 713 - | _ -> raise (Json.Of_json ("Missing or invalid 'id' field", `Assoc fields)) 717 + | _ -> Util.json_error "Missing or invalid 'id' field" json 714 718 in 715 719 let error = match List.assoc_opt "error" fields with 716 720 | Some (`Assoc error_fields) -> error_fields 717 - | _ -> raise (Json.Of_json ("Missing or invalid 'error' field", `Assoc fields)) 721 + | _ -> Util.json_error "Missing or invalid 'error' field" json 718 722 in 719 723 let code = match List.assoc_opt "code" error with 720 724 | Some (`Int code) -> code 721 - | _ -> raise (Json.Of_json ("Missing or invalid 'code' field in error", `Assoc error)) 725 + | _ -> Util.json_error "Missing or invalid 'code' field in error" (`Assoc error) 722 726 in 723 727 let message = match List.assoc_opt "message" error with 724 728 | Some (`String msg) -> msg 725 - | _ -> raise (Json.Of_json ("Missing or invalid 'message' field in error", `Assoc error)) 729 + | _ -> Util.json_error "Missing or invalid 'message' field in error" (`Assoc error) 726 730 in 727 731 let data = List.assoc_opt "data" error in 728 732 { id; code; message; data } 729 - | j -> raise (Json.Of_json ("Expected object for error", j)) 733 + | j -> Util.json_error "Expected object for error" j 730 734 731 735 let t_of_yojson json = 732 736 match json with 733 737 | `Assoc fields -> 734 738 let _jsonrpc = match List.assoc_opt "jsonrpc" fields with 735 739 | Some (`String "2.0") -> () 736 - | _ -> raise (Json.Of_json ("Missing or invalid 'jsonrpc' field", json)) 740 + | _ -> Util.json_error "Missing or invalid 'jsonrpc' field" json 737 741 in 738 742 if List.mem_assoc "method" fields then 739 743 if List.mem_assoc "id" fields then ··· 745 749 else if List.mem_assoc "error" fields then 746 750 Error (error_of_yojson json) 747 751 else 748 - raise (Json.Of_json ("Invalid JSONRPC message format", json)) 749 - | j -> raise (Json.Of_json ("Expected object for JSONRPC message", j)) 752 + Util.json_error "Invalid JSONRPC message format" json 753 + | j -> Util.json_error "Expected object for JSONRPC message" j 750 754 751 755 let create_notification ?(params=None) ~meth () = 752 756 Notification { meth; params } ··· 782 786 | `Assoc fields as json -> 783 787 let capabilities = match List.assoc_opt "capabilities" fields with 784 788 | Some json -> json 785 - | None -> raise (Json.Of_json ("Missing capabilities field", json)) 789 + | None -> Util.json_error "Missing capabilities field" json 786 790 in 787 791 let client_info = match List.assoc_opt "clientInfo" fields with 788 792 | Some json -> Implementation.t_of_yojson json 789 - | None -> raise (Json.Of_json ("Missing clientInfo field", json)) 793 + | None -> Util.json_error "Missing clientInfo field" json 790 794 in 791 795 let protocol_version = Util.get_string_field fields "protocolVersion" json in 792 796 { capabilities; client_info; protocol_version } 793 - | j -> raise (Json.Of_json ("Expected object for InitializeRequest", j)) 797 + | j -> Util.json_error "Expected object for InitializeRequest" j 794 798 795 799 let create ~capabilities ~client_info ~protocol_version = 796 800 { capabilities; client_info; protocol_version } ··· 829 833 | `Assoc fields as json -> 830 834 let capabilities = match List.assoc_opt "capabilities" fields with 831 835 | Some json -> json 832 - | None -> raise (Json.Of_json ("Missing capabilities field", json)) 836 + | None -> Util.json_error "Missing capabilities field" json 833 837 in 834 838 let server_info = match List.assoc_opt "serverInfo" fields with 835 839 | Some json -> Implementation.t_of_yojson json 836 - | None -> raise (Json.Of_json ("Missing serverInfo field", json)) 840 + | None -> Util.json_error "Missing serverInfo field" json 837 841 in 838 842 let protocol_version = Util.get_string_field fields "protocolVersion" json in 839 843 let instructions = Util.get_optional_string_field fields "instructions" in 840 844 let meta = List.assoc_opt "_meta" fields in 841 845 { capabilities; server_info; protocol_version; instructions; meta } 842 - | j -> raise (Json.Of_json ("Expected object for InitializeResult", j)) 846 + | j -> Util.json_error "Expected object for InitializeResult" j 843 847 844 848 let create ~capabilities ~server_info ~protocol_version ?instructions ?meta () = 845 849 { capabilities; server_info; protocol_version; instructions; meta } ··· 867 871 | `Assoc fields -> 868 872 let meta = List.assoc_opt "_meta" fields in 869 873 { meta } 870 - | j -> raise (Json.Of_json ("Expected object for InitializedNotification", j)) 874 + | j -> Util.json_error "Expected object for InitializedNotification" j 871 875 872 876 let create ?meta () = { meta } 873 877
+8
lib/mcp.mli
··· 25 25 26 26 (** Utility functions for JSON parsing *) 27 27 module Util : sig 28 + (** Helper to raise a Json.Of_json exception with formatted message 29 + @param fmt Format string for the error message 30 + @param json JSON value to include in the exception 31 + @return Never returns, always raises an exception 32 + @raise Json.Of_json with the formatted message and JSON value 33 + *) 34 + val json_error : ('a, unit, string, 'b) format4 -> Json.t -> 'a 35 + 28 36 (** Extract a string field from JSON object or raise an error 29 37 @param fields Assoc list of fields from JSON object 30 38 @param name Field name to extract
+65 -65
lib/mcp_rpc.ml
··· 22 22 | `Assoc fields -> 23 23 let cursor = List.assoc_opt "cursor" fields |> Option.map Cursor.t_of_yojson in 24 24 { cursor } 25 - | j -> raise (Json.Of_json ("Expected object for ResourcesList.Request.t", j)) 25 + | j -> Util.json_error "Expected object for ResourcesList.Request.t" j 26 26 27 27 end 28 28 ··· 55 55 `Assoc assoc 56 56 57 57 let t_of_yojson = function 58 - | `Assoc fields -> 58 + | `Assoc fields as json -> 59 59 let uri = match List.assoc_opt "uri" fields with 60 60 | Some (`String s) -> s 61 - | _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields)) 61 + | _ -> Util.json_error "Missing or invalid 'uri' field" json 62 62 in 63 63 let name = match List.assoc_opt "name" fields with 64 64 | Some (`String s) -> s 65 - | _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields)) 65 + | _ -> Util.json_error "Missing or invalid 'name' field" json 66 66 in 67 67 let description = List.assoc_opt "description" fields |> Option.map (function 68 68 | `String s -> s 69 - | j -> raise (Json.Of_json ("Expected string for description", j)) 69 + | j -> Util.json_error "Expected string for description" j 70 70 ) in 71 71 let mime_type = List.assoc_opt "mimeType" fields |> Option.map (function 72 72 | `String s -> s 73 - | j -> raise (Json.Of_json ("Expected string for mimeType", j)) 73 + | j -> Util.json_error "Expected string for mimeType" j 74 74 ) in 75 75 let size = List.assoc_opt "size" fields |> Option.map (function 76 76 | `Int i -> i 77 - | j -> raise (Json.Of_json ("Expected int for size", j)) 77 + | j -> Util.json_error "Expected int for size" j 78 78 ) in 79 79 { uri; name; description; mime_type; size } 80 - | j -> raise (Json.Of_json ("Expected object for ResourcesList.Resource.t", j)) 80 + | j -> Util.json_error "Expected object for ResourcesList.Resource.t" j 81 81 end 82 82 83 83 module Response = struct ··· 97 97 `Assoc assoc 98 98 99 99 let t_of_yojson = function 100 - | `Assoc fields -> 100 + | `Assoc fields as json -> 101 101 let resources = match List.assoc_opt "resources" fields with 102 102 | Some (`List items) -> List.map Resource.t_of_yojson items 103 - | _ -> raise (Json.Of_json ("Missing or invalid 'resources' field", `Assoc fields)) 103 + | _ -> Util.json_error "Missing or invalid 'resources' field" json 104 104 in 105 105 let next_cursor = List.assoc_opt "nextCursor" fields |> Option.map Cursor.t_of_yojson in 106 106 { resources; next_cursor } 107 - | j -> raise (Json.Of_json ("Expected object for ResourcesList.Response.t", j)) 107 + | j -> Util.json_error "Expected object for ResourcesList.Response.t" j 108 108 109 109 end 110 110 ··· 135 135 ] 136 136 137 137 let t_of_yojson = function 138 - | `Assoc fields -> 138 + | `Assoc fields as json -> 139 139 let uri = match List.assoc_opt "uri" fields with 140 140 | Some (`String s) -> s 141 - | _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields)) 141 + | _ -> Util.json_error "Missing or invalid 'uri' field" json 142 142 in 143 143 { uri } 144 - | j -> raise (Json.Of_json ("Expected object for ResourcesRead.Request.t", j)) 144 + | j -> Util.json_error "Expected object for ResourcesRead.Request.t" j 145 145 146 146 end 147 147 ··· 162 162 else if List.mem_assoc "blob" fields then 163 163 BlobResource (BlobResourceContents.t_of_yojson json) 164 164 else 165 - raise (Json.Of_json ("Invalid resource content", json)) 166 - | j -> raise (Json.Of_json ("Expected object for ResourcesRead.ResourceContent.t", j)) 165 + Util.json_error "Invalid resource content" json 166 + | j -> Util.json_error "Expected object for ResourcesRead.ResourceContent.t" j 167 167 168 168 end 169 169 ··· 178 178 ] 179 179 180 180 let t_of_yojson = function 181 - | `Assoc fields -> 181 + | `Assoc fields as json -> 182 182 let contents = match List.assoc_opt "contents" fields with 183 183 | Some (`List items) -> List.map ResourceContent.t_of_yojson items 184 - | _ -> raise (Json.Of_json ("Missing or invalid 'contents' field", `Assoc fields)) 184 + | _ -> Util.json_error "Missing or invalid 'contents' field" json 185 185 in 186 186 { contents } 187 - | j -> raise (Json.Of_json ("Expected object for ResourcesRead.Response.t", j)) 187 + | j -> Util.json_error "Expected object for ResourcesRead.Response.t" j 188 188 189 189 end 190 190 ··· 221 221 | `Assoc fields -> 222 222 let cursor = List.assoc_opt "cursor" fields |> Option.map Cursor.t_of_yojson in 223 223 { cursor } 224 - | j -> raise (Json.Of_json ("Expected object for ToolsList.Request.t", j)) 224 + | j -> Util.json_error "Expected object for ToolsList.Request.t" j 225 225 226 226 end 227 227 ··· 249 249 `Assoc assoc 250 250 251 251 let t_of_yojson = function 252 - | `Assoc fields -> 252 + | `Assoc fields as json -> 253 253 let name = match List.assoc_opt "name" fields with 254 254 | Some (`String s) -> s 255 - | _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields)) 255 + | _ -> Util.json_error "Missing or invalid 'name' field" json 256 256 in 257 257 let description = List.assoc_opt "description" fields |> Option.map (function 258 258 | `String s -> s 259 - | j -> raise (Json.Of_json ("Expected string for description", j)) 259 + | j -> Util.json_error "Expected string for description" j 260 260 ) in 261 261 let input_schema = match List.assoc_opt "inputSchema" fields with 262 262 | Some schema -> schema 263 - | None -> raise (Json.Of_json ("Missing 'inputSchema' field", `Assoc fields)) 263 + | None -> Util.json_error "Missing 'inputSchema' field" json 264 264 in 265 265 let annotations = List.assoc_opt "annotations" fields in 266 266 { name; description; input_schema; annotations } 267 - | j -> raise (Json.Of_json ("Expected object for ToolsList.Tool.t", j)) 267 + | j -> Util.json_error "Expected object for ToolsList.Tool.t" j 268 268 269 269 end 270 270 ··· 285 285 `Assoc assoc 286 286 287 287 let t_of_yojson = function 288 - | `Assoc fields -> 288 + | `Assoc fields as json -> 289 289 let tools = match List.assoc_opt "tools" fields with 290 290 | Some (`List items) -> List.map Tool.t_of_yojson items 291 - | _ -> raise (Json.Of_json ("Missing or invalid 'tools' field", `Assoc fields)) 291 + | _ -> Util.json_error "Missing or invalid 'tools' field" json 292 292 in 293 293 let next_cursor = List.assoc_opt "nextCursor" fields |> Option.map Cursor.t_of_yojson in 294 294 { tools; next_cursor } 295 - | j -> raise (Json.Of_json ("Expected object for ToolsList.Response.t", j)) 295 + | j -> Util.json_error "Expected object for ToolsList.Response.t" j 296 296 297 297 end 298 298 ··· 325 325 ] 326 326 327 327 let t_of_yojson = function 328 - | `Assoc fields -> 328 + | `Assoc fields as json -> 329 329 let name = match List.assoc_opt "name" fields with 330 330 | Some (`String s) -> s 331 - | _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields)) 331 + | _ -> Util.json_error "Missing or invalid 'name' field" json 332 332 in 333 333 let arguments = match List.assoc_opt "arguments" fields with 334 334 | Some json -> json 335 - | None -> raise (Json.Of_json ("Missing 'arguments' field", `Assoc fields)) 335 + | None -> Util.json_error "Missing 'arguments' field" json 336 336 in 337 337 { name; arguments } 338 - | j -> raise (Json.Of_json ("Expected object for ToolsCall.Request.t", j)) 338 + | j -> Util.json_error "Expected object for ToolsCall.Request.t" j 339 339 340 340 end 341 341 ··· 360 360 | Some (`String "image") -> Image (ImageContent.t_of_yojson json) 361 361 | Some (`String "audio") -> Audio (AudioContent.t_of_yojson json) 362 362 | Some (`String "resource") -> Resource (EmbeddedResource.t_of_yojson json) 363 - | _ -> raise (Json.Of_json ("Invalid or missing content type", json))) 364 - | j -> raise (Json.Of_json ("Expected object for ToolsCall.ToolContent.t", j)) 363 + | _ -> Util.json_error "Invalid or missing content type" json) 364 + | j -> Util.json_error "Expected object for ToolsCall.ToolContent.t" j 365 365 366 366 end 367 367 ··· 378 378 ] 379 379 380 380 let t_of_yojson = function 381 - | `Assoc fields -> 381 + | `Assoc fields as json -> 382 382 let content = match List.assoc_opt "content" fields with 383 383 | Some (`List items) -> List.map ToolContent.t_of_yojson items 384 - | _ -> raise (Json.Of_json ("Missing or invalid 'content' field", `Assoc fields)) 384 + | _ -> Util.json_error "Missing or invalid 'content' field" json 385 385 in 386 386 let is_error = match List.assoc_opt "isError" fields with 387 387 | Some (`Bool b) -> b 388 388 | _ -> false 389 389 in 390 390 { content; is_error } 391 - | j -> raise (Json.Of_json ("Expected object for ToolsCall.Response.t", j)) 391 + | j -> Util.json_error "Expected object for ToolsCall.Response.t" j 392 392 393 393 end 394 394 ··· 431 431 `Assoc assoc 432 432 433 433 let t_of_yojson = function 434 - | `Assoc fields -> 434 + | `Assoc fields as json -> 435 435 let name = match List.assoc_opt "name" fields with 436 436 | Some (`String s) -> s 437 - | _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields)) 437 + | _ -> Util.json_error "Missing or invalid 'name' field" json 438 438 in 439 439 let description = List.assoc_opt "description" fields |> Option.map (function 440 440 | `String s -> s 441 - | j -> raise (Json.Of_json ("Expected string for description", j)) 441 + | j -> Util.json_error "Expected string for description" j 442 442 ) in 443 443 let required = match List.assoc_opt "required" fields with 444 444 | Some (`Bool b) -> b 445 445 | _ -> false 446 446 in 447 447 { name; description; required } 448 - | j -> raise (Json.Of_json ("Expected object for PromptsList.PromptArgument.t", j)) 448 + | j -> Util.json_error "Expected object for PromptsList.PromptArgument.t" j 449 449 450 450 end 451 451 ··· 472 472 `Assoc assoc 473 473 474 474 let t_of_yojson = function 475 - | `Assoc fields -> 475 + | `Assoc fields as json -> 476 476 let name = match List.assoc_opt "name" fields with 477 477 | Some (`String s) -> s 478 - | _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields)) 478 + | _ -> Util.json_error "Missing or invalid 'name' field" json 479 479 in 480 480 let description = List.assoc_opt "description" fields |> Option.map (function 481 481 | `String s -> s 482 - | j -> raise (Json.Of_json ("Expected string for description", j)) 482 + | j -> Util.json_error "Expected string for description" j 483 483 ) in 484 484 let arguments = match List.assoc_opt "arguments" fields with 485 485 | Some (`List items) -> List.map PromptArgument.t_of_yojson items 486 486 | _ -> [] 487 487 in 488 488 { name; description; arguments } 489 - | j -> raise (Json.Of_json ("Expected object for PromptsList.Prompt.t", j)) 489 + | j -> Util.json_error "Expected object for PromptsList.Prompt.t" j 490 490 491 491 end 492 492 ··· 507 507 | `Assoc fields -> 508 508 let cursor = List.assoc_opt "cursor" fields |> Option.map Cursor.t_of_yojson in 509 509 { cursor } 510 - | j -> raise (Json.Of_json ("Expected object for PromptsList.Request.t", j)) 510 + | j -> Util.json_error "Expected object for PromptsList.Request.t" j 511 511 512 512 end 513 513 ··· 528 528 `Assoc assoc 529 529 530 530 let t_of_yojson = function 531 - | `Assoc fields -> 531 + | `Assoc fields as json -> 532 532 let prompts = match List.assoc_opt "prompts" fields with 533 533 | Some (`List items) -> List.map Prompt.t_of_yojson items 534 - | _ -> raise (Json.Of_json ("Missing or invalid 'prompts' field", `Assoc fields)) 534 + | _ -> Util.json_error "Missing or invalid 'prompts' field" json 535 535 in 536 536 let next_cursor = List.assoc_opt "nextCursor" fields |> Option.map Cursor.t_of_yojson in 537 537 { prompts; next_cursor } 538 - | j -> raise (Json.Of_json ("Expected object for PromptsList.Response.t", j)) 538 + | j -> Util.json_error "Expected object for PromptsList.Response.t" j 539 539 540 540 end 541 541 ··· 569 569 ] 570 570 571 571 let t_of_yojson = function 572 - | `Assoc fields -> 572 + | `Assoc fields as json -> 573 573 let name = match List.assoc_opt "name" fields with 574 574 | Some (`String s) -> s 575 - | _ -> raise (Json.Of_json ("Missing or invalid 'name' field", `Assoc fields)) 575 + | _ -> Util.json_error "Missing or invalid 'name' field" json 576 576 in 577 577 let arguments = match List.assoc_opt "arguments" fields with 578 578 | Some (`Assoc args) -> 579 579 List.map (fun (k, v) -> 580 580 match v with 581 581 | `String s -> (k, s) 582 - | _ -> raise (Json.Of_json ("Expected string value for argument", v)) 582 + | _ -> Util.json_error "Expected string value for argument" v 583 583 ) args 584 584 | _ -> [] 585 585 in 586 586 { name; arguments } 587 - | j -> raise (Json.Of_json ("Expected object for PromptsGet.Request.t", j)) 587 + | j -> Util.json_error "Expected object for PromptsGet.Request.t" j 588 588 589 589 end 590 590 ··· 605 605 `Assoc assoc 606 606 607 607 let t_of_yojson = function 608 - | `Assoc fields -> 608 + | `Assoc fields as json -> 609 609 let messages = match List.assoc_opt "messages" fields with 610 610 | Some (`List items) -> List.map PromptMessage.t_of_yojson items 611 - | _ -> raise (Json.Of_json ("Missing or invalid 'messages' field", `Assoc fields)) 611 + | _ -> Util.json_error "Missing or invalid 'messages' field" json 612 612 in 613 613 let description = List.assoc_opt "description" fields |> Option.map (function 614 614 | `String s -> s 615 - | j -> raise (Json.Of_json ("Expected string for description", j)) 615 + | j -> Util.json_error "Expected string for description" j 616 616 ) in 617 617 { description; messages } 618 - | j -> raise (Json.Of_json ("Expected object for PromptsGet.Response.t", j)) 618 + | j -> Util.json_error "Expected object for PromptsGet.Response.t" j 619 619 620 620 end 621 621 ··· 660 660 ] 661 661 662 662 let t_of_yojson = function 663 - | `Assoc fields -> 663 + | `Assoc fields as json -> 664 664 let uri = match List.assoc_opt "uri" fields with 665 665 | Some (`String s) -> s 666 - | _ -> raise (Json.Of_json ("Missing or invalid 'uri' field", `Assoc fields)) 666 + | _ -> Util.json_error "Missing or invalid 'uri' field" json 667 667 in 668 668 { uri } 669 - | j -> raise (Json.Of_json ("Expected object for ResourceUpdated.Notification.t", j)) 669 + | j -> Util.json_error "Expected object for ResourceUpdated.Notification.t" j 670 670 671 671 end 672 672 ··· 692 692 ] 693 693 694 694 let t_of_yojson = function 695 - | `Assoc fields -> 695 + | `Assoc fields as json -> 696 696 let progress = match List.assoc_opt "progress" fields with 697 697 | Some (`Float f) -> f 698 - | _ -> raise (Json.Of_json ("Missing or invalid 'progress' field", `Assoc fields)) 698 + | _ -> Util.json_error "Missing or invalid 'progress' field" json 699 699 in 700 700 let total = match List.assoc_opt "total" fields with 701 701 | Some (`Float f) -> f 702 - | _ -> raise (Json.Of_json ("Missing or invalid 'total' field", `Assoc fields)) 702 + | _ -> Util.json_error "Missing or invalid 'total' field" json 703 703 in 704 704 let progress_token = match List.assoc_opt "progressToken" fields with 705 705 | Some token -> ProgressToken.t_of_yojson token 706 - | _ -> raise (Json.Of_json ("Missing or invalid 'progressToken' field", `Assoc fields)) 706 + | _ -> Util.json_error "Missing or invalid 'progressToken' field" json 707 707 in 708 708 { progress; total; progress_token } 709 - | j -> raise (Json.Of_json ("Expected object for Progress.Notification.t", j)) 709 + | j -> Util.json_error "Expected object for Progress.Notification.t" j 710 710 711 711 end 712 712