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

View File

@ -25,9 +25,6 @@ module StringMap : Map.S with type key = string
type t = Yojson.Safe.t StringMap.t
(** 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
(** [extract_frontmatter content] extracts the YAML frontmatter from the
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
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.
@param content The frontmatter part of the markdown content
@return
A map where keys are frontmatter field names and values are the
corresponding JSON values preserving their original types
@raise Frontmatter_parse_error
if the YAML parsing fails or if the frontmatter is not a valid YAML
object/map
A result object which when Ok, contains a map where keys are frontmatter
field names and values are the corresponding JSON values preserving their
original types. When error, contains an error message indicating the
parsing failure(s).
Returns an empty map if:
- 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. *)

View File

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

View File

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