Skip to content

Commit 9f9f156

Browse files
committed
Improve error handling when no format is resolved
1 parent 6683356 commit 9f9f156

File tree

5 files changed

+40
-20
lines changed

5 files changed

+40
-20
lines changed

lib/cldr/backend/date_time.ex

+2-2
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ defmodule Cldr.DateAndTime.Backend do
247247
# CLDR defined format.
248248
iex> #{inspect(__MODULE__)}.to_string(%{year: 2024, day: 3}, locale: "fr")
249249
{:error,
250-
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for \\"dy\\""}}
250+
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :dy"}}
251251
252252
"""
253253
@spec to_string(Cldr.Calendar.any_date_time(), Keyword.t()) ::
@@ -408,7 +408,7 @@ defmodule Cldr.DateAndTime.Backend do
408408
# CLDR defined format.
409409
iex> #{inspect(__MODULE__)}.to_string(%{minute: 11})
410410
{:error,
411-
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for \\"m\\""}}
411+
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :m"}}
412412
413413
"""
414414
@spec to_string(Cldr.Calendar.any_date_time(), Keyword.t()) ::

lib/cldr/date.ex

+16-4
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ defmodule Cldr.Date do
118118
# CLDR-defined format.
119119
iex> Cldr.Date.to_string(%{year: 2024, day: 3}, MyApp.Cldr, locale: "fr")
120120
{:error,
121-
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for \\"dy\\""}}
121+
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :dy"}}
122122
123123
"""
124124
@spec to_string(Cldr.Calendar.any_date_time(), Cldr.backend() | Keyword.t(), Keyword.t()) ::
@@ -464,9 +464,7 @@ defmodule Cldr.Date do
464464
if Map.has_key?(available_formats, format) do
465465
Map.fetch(available_formats, format)
466466
else
467-
with {:ok, match} <- Cldr.DateTime.Format.best_match(format, locale, calendar, backend) do
468-
{:ok, Map.fetch!(available_formats, match)}
469-
end
467+
resolve_format(format, available_formats, locale, calendar, backend)
470468
end
471469
end
472470

@@ -478,6 +476,20 @@ defmodule Cldr.Date do
478476
{:ok, format_string}
479477
end
480478

479+
@doc false
480+
def resolve_format(format, available_formats, locale, calendar, backend) do
481+
with {:ok, match} <- Cldr.DateTime.Format.best_match(format, locale, calendar, backend),
482+
{:ok, format} <- Map.fetch(available_formats, match) do
483+
{:ok, format}
484+
else
485+
:error ->
486+
{:error, Cldr.DateTime.Format.no_format_resolved_error(format)}
487+
488+
other ->
489+
other
490+
end
491+
end
492+
481493
defp error_return(map, requirements) do
482494
requirements =
483495
requirements

lib/cldr/format/date_time_format.ex

+14-7
Original file line numberDiff line numberDiff line change
@@ -632,13 +632,13 @@ defmodule Cldr.DateTime.Format do
632632
) :: {:ok, format_id()} | {:error, {module(), String.t()}}
633633

634634
def best_match(
635-
skeleton,
635+
original_skeleton,
636636
locale \\ Cldr.get_locale(),
637637
calendar \\ Cldr.Calendar.default_cldr_calendar(),
638638
backend \\ Cldr.Date.default_backend()
639639
) do
640640
with {:ok, locale} <- Cldr.validate_locale(locale, backend),
641-
skeleton = to_string(skeleton),
641+
skeleton = to_string(original_skeleton),
642642
{:ok, skeleton} <- put_preferred_time_symbols(skeleton, locale),
643643
{:ok, skeleton_tokens} <- Compiler.tokenize_skeleton(skeleton) do
644644
# match_with_day_periods? =
@@ -663,18 +663,22 @@ defmodule Cldr.DateTime.Format do
663663

664664
case candidates do
665665
[] ->
666-
{:error,
667-
{
668-
Cldr.DateTime.UnresolvedFormat,
669-
"No available format resolved for #{inspect(skeleton)}"
670-
}}
666+
{:error, no_format_resolved_error(original_skeleton)}
671667

672668
[{format_id, _} | _rest] ->
673669
{:ok, format_id}
674670
end
675671
end
676672
end
677673

674+
@doc false
675+
def no_format_resolved_error(skeleton) do
676+
{
677+
Cldr.DateTime.UnresolvedFormat,
678+
"No available format resolved for #{inspect(skeleton)}"
679+
}
680+
end
681+
678682
# https://www.unicode.org/reports/tr35/tr35-dates.html#Matching_Skeletons
679683
# For skeleton and id fields with symbols representing the same type (year, month, day, etc):
680684
# Most symbols have a small distance from each other.
@@ -785,6 +789,9 @@ defmodule Cldr.DateTime.Format do
785789
when different_but_compatible({symbol_a, count_a}, {symbol_b, count_b}) and
786790
different_types({symbol_a, count_a}, {symbol_b, count_b}) ->
787791
acc + abs(count_a - count_b) + 10
792+
793+
_other_a, _other_b, acc ->
794+
acc + 10
788795
end)
789796

790797
{token_id, distance}

lib/cldr/time.ex

+5-4
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ defmodule Cldr.Time do
125125
# CLDR-defined format.
126126
iex> Cldr.Time.to_string(%{minute: 11})
127127
{:error,
128-
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for \\"m\\""}}
128+
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :m"}}
129129
130130
"""
131131
@spec to_string(map, Cldr.backend() | Keyword.t(), Keyword.t()) ::
@@ -347,9 +347,7 @@ defmodule Cldr.Time do
347347
if Map.has_key?(available_formats, format) do
348348
Map.fetch(available_formats, format)
349349
else
350-
with {:ok, match} <- Cldr.DateTime.Format.best_match(format, locale, calendar, backend) do
351-
{:ok, Map.fetch!(available_formats, match)}
352-
end
350+
resolve_format(format, available_formats, locale, calendar, backend)
353351
end
354352
end
355353

@@ -361,6 +359,9 @@ defmodule Cldr.Time do
361359
{:ok, format_string}
362360
end
363361

362+
@doc false
363+
defdelegate resolve_format(format, available_formats, locale, calendar, backend), to: Cldr.Date
364+
364365
@doc """
365366
Returns a map of the standard time formats for a given
366367
locale and calendar.

test/partial_date_times_test.exs

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ defmodule Cldr.DateTime.PartialTest do
1515

1616
assert Cldr.Date.to_string(%{year: 3, day: 5}) ==
1717
{:error,
18-
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for \"dy\""}}
18+
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :dy"}}
1919
end
2020

2121
test "Partial Times" do
@@ -43,7 +43,7 @@ defmodule Cldr.DateTime.PartialTest do
4343

4444
assert Cldr.Time.to_string(%{hour: 23, second: 45}) ==
4545
{:error,
46-
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for \"sh\""}}
46+
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :sh"}}
4747

4848
assert Cldr.Time.to_string(%{hour: 23, second: 45}, format: "h:m:s") ==
4949
{:error,
@@ -58,7 +58,7 @@ defmodule Cldr.DateTime.PartialTest do
5858

5959
assert Cldr.DateTime.to_string(%{year: 2024, minute: 10}) ==
6060
{:error,
61-
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for \"m\""}}
61+
{Cldr.DateTime.UnresolvedFormat, "No available format resolved for :m"}}
6262

6363
end
6464

0 commit comments

Comments
 (0)