use Result type instead of raising exception

This commit is contained in:
Kaustubh Maske Patil 2025-05-31 22:21:25 +05:30
parent 5df24957c2
commit a6fd0fcc2c
4 changed files with 28 additions and 46 deletions

View File

@ -1,8 +1,6 @@
module Y = Hl_yaml.Unix module Y = Hl_yaml.Unix
module StringMap = Map.Make (String) module StringMap = Map.Make (String)
exception Frontmatter_parse_error of string
(* Type for frontmatter data *) (* Type for frontmatter data *)
type t = Yojson.Safe.t StringMap.t type t = Yojson.Safe.t StringMap.t
@ -56,15 +54,10 @@ let yojson_to_string_map = function
StringMap.empty assoc) StringMap.empty assoc)
| _ -> Error "Frontmatter must be a YAML object/map" | _ -> Error "Frontmatter must be a YAML object/map"
let parse_frontmatter (yaml_content : string) : t = let parse_frontmatter (yaml_content : string) : (t, string) Result.t =
if String.trim yaml_content = "" then StringMap.empty let options = Y.make_options ~enable_imports:false () in
else match Y.parse ~options ~of_yojson:yojson_to_string_map yaml_content with
try | Ok fm -> Ok fm
let options = Y.make_options ~enable_imports:false () in | Error error_list ->
let result = Error
Y.parse ~options ~of_yojson:yojson_to_string_map yaml_content (List.map Hl_yaml.Spec.error_to_string error_list |> String.concat "\n")
in
Y.ok_or_raise result
with exn ->
raise
(Frontmatter_parse_error ("Parsing failed: " ^ Printexc.to_string exn))

View File

@ -25,9 +25,6 @@ module StringMap : Map.S with type key = string
type t = Yojson.Safe.t StringMap.t type t = Yojson.Safe.t StringMap.t
(** Type representing the frontmatter as a map of string keys to JSON values. *) (** Type representing the frontmatter as a map of string keys to JSON values. *)
exception Frontmatter_parse_error of string
(** Exception raised when frontmatter parsing fails. *)
val extract_frontmatter : string -> string * string val extract_frontmatter : string -> string * string
(** [extract_frontmatter content] extracts the YAML frontmatter from the (** [extract_frontmatter content] extracts the YAML frontmatter from the
beginning of the markdown content. It returns the YAML part and the rest of beginning of the markdown content. It returns the YAML part and the rest of
@ -45,22 +42,17 @@ val extract_frontmatter : string -> string * string
markdown file, it must not be silently parsed as content. A YAML parsing markdown file, it must not be silently parsed as content. A YAML parsing
error whenever the parsing happens is desired instead. *) error whenever the parsing happens is desired instead. *)
val parse_frontmatter : string -> t val parse_frontmatter : string -> (t, string) Result.t
(** [parse_frontmatter content] parses YAML frontmatter from a string. (** [parse_frontmatter content] parses YAML frontmatter from a string.
@param content The frontmatter part of the markdown content @param content The frontmatter part of the markdown content
@return @return
A map where keys are frontmatter field names and values are the A result object which when Ok, contains a map where keys are frontmatter
corresponding JSON values preserving their original types field names and values are the corresponding JSON values preserving their
original types. When error, contains an error message indicating the
@raise Frontmatter_parse_error parsing failure(s).
if the YAML parsing fails or if the frontmatter is not a valid YAML
object/map
Returns an empty map if: Returns an empty map if:
- The frontmatter section is empty - The frontmatter section is empty
The function expects frontmatter to be:
- Valid YAML that parses to an object/map structure
Security note: File imports are disabled during parsing for security. *) Security note: File imports are disabled during parsing for security. *)

View File

@ -1,7 +1,3 @@
module UserPage = struct module UserPage = struct
type t = { frontmatter : Frontmatter.t; content : string } type t = { frontmatter : Frontmatter.t; content : string }
(* let of_string (content : string) : t =
match Frontmatter.extract_frontmatter content with
| (yaml_content, remaining_content) -> *)
end end

View File

@ -75,19 +75,20 @@ let%test "extract content from md with invalid frontmatter" =
String.trim content = {|" # bad yaml|} String.trim content = {|" # bad yaml|}
let%test "parse valid yaml" = let%test "parse valid yaml" =
let fm = parse_frontmatter simple_markdown_yaml_section in match parse_frontmatter simple_markdown_yaml_section with
let expected = | Error _ -> false
StringMap.of_list | Ok fm ->
[ let expected =
("Title", `String "Test Document"); StringMap.of_list
("Draft", `Bool true); [
("Date", `String "2023-10-01"); ("Title", `String "Test Document");
] ("Draft", `Bool true);
in ("Date", `String "2023-10-01");
StringMap.equal Yojson.Safe.equal fm expected ]
in
StringMap.equal Yojson.Safe.equal fm expected
let%test "parse invalid yaml raises Frontmatter_parse_error" = let%test "parse invalid yaml should error" =
try match parse_frontmatter invalid_yaml_frontmatter with
ignore (parse_frontmatter invalid_yaml_frontmatter); | Error _ -> true
false | Ok _ -> false
with Frontmatter_parse_error _ -> true