<chrono>
: Improve exception messages when OS support is unavailable for time zones
#4331
Labels
<chrono>
: Improve exception messages when OS support is unavailable for time zones
#4331
Overview
The STL's VS 2019 16.10 Changelog explained:
When OS support is unavailable, we throw exceptions, as permitted by the Standard. However, if a programmer isn't already aware of the OS version dependency here, deducing "the end user's OS is too old" from the exception message can be an excessively mysterious process.
#1911 asks whether a fallback mechanism can be implemented for old OSes. There are no current plans to do so, and I believe that this will remain infeasible. However, it should be fairly simple to enhance the exception messages here.
Leap seconds require Windows 10 version 1809 or later
I believe that this happens in
__std_tzdb_get_leap_seconds
:STL/stl/src/tzdb.cpp
Lines 597 to 601 in 442029c
For old OSes, I don't believe that we throw an exception:
STL/stl/inc/chrono
Lines 2167 to 2175 in 442029c
It looks like we silently say "there's no post-2018 leap second data" for old OSes. If I'm right, then there's no exception message that needs to be enhanced here. (Leap seconds are also much less "popular" than time zones.)
Time zones require Windows 10 version 1903/19H1 or later
_Init_icu_functions
is the single place where we loadicu.dll
:STL/stl/src/tzdb.cpp
Line 66 in 442029c
The only caller is the wrapper
_Acquire_icu_functions
:STL/stl/src/tzdb.cpp
Lines 101 to 108 in 442029c
Which in turn has 3 callsites:
__std_tzdb_get_time_zones
,__std_tzdb_get_current_zone
,__std_tzdb_get_sys_info
:STL/stl/src/tzdb.cpp
Lines 357 to 358 in 442029c
STL/stl/src/tzdb.cpp
Lines 460 to 461 in 442029c
STL/stl/src/tzdb.cpp
Lines 501 to 502 in 442029c
They all report
__std_tzdb_error::_Win_error
(because we haven't even loaded ICU yet;_Icu_error
is for when we've loaded ICU but it fails later). They're all called via_Make_unique_tzdb_info
:STL/stl/inc/chrono
Lines 1837 to 1838 in 442029c
STL/stl/inc/chrono
Line 2069 in 442029c
STL/stl/inc/chrono
Line 2110 in 442029c
Which has conveniently extracted the common pattern here (thanks to #4119):
STL/stl/inc/chrono
Lines 1743 to 1757 in 442029c
Therefore, I believe that the
_XGetLastError()
is the single location that we need to modify. Unfortunately,_XGetLastError()
was not designed to be extensible - it combines callingGetLastError()
and throwing asystem_error
with it:STL/stl/src/xonce.cpp
Lines 21 to 25 in 442029c
To throw a better exception here, without try-catch-rethrow, we'd need to inject a new function into the import lib. (I think we should continue to capture
GetLastError()
, but provide an additional message mentioning that the OS version may be relevant.)Suggested message
Windows versioning is complicated (but not nearly as much as MSVC versioning 😹) so for clarity I suggest a message like:
"C++20 chrono time zone support requires Windows 10 version 1903/19H1, Windows 11, Windows Server 2022, or later."
The text was updated successfully, but these errors were encountered: