Repair release. Five of the eight data functions were broken against the live OECD API and returned nothing, or in one case an empty frame, without saying why. All five work again.
oecd_fetch() wrapped req_perform() in a
tryCatch that reported every failure as “Failed to reach
the OECD API. Check your internet connection”. Because
req_perform() raises on 4xx and 5xx by default, that
handler caught every HTTP error the API returned, so a 404 or a rate
limit looked like a broken network. It also made the 429 and 404
branches further down the function unreachable: they had never run. The
response is now allowed through with
req_error(is_error = FALSE), and the tryCatch
catches only genuine transport failures.
With the real errors visible, five separate upstream changes turned up. Nothing had been withdrawn; the OECD had moved versions and renamed codes.
| Function | Cause | Fix |
|---|---|---|
get_oecd_tax() |
Dataflow gained a CTRY_SPECIFIC_REVENUE dimension, so
the filter was one position short and returned HTTP 422 |
Added the position |
get_oecd_health() |
Requesting version 1.0 of a dataflow now at 1.1 returns no records | Bumped to 1.1, and PT_GDP became
PT_B1GQ |
get_oecd_deficit() |
CHAPTER = "_Z" matched nothing |
Left the dimension open |
get_oecd_current_account() |
COUNTERPART_AREA, FS_ENTRY and
ADJUSTMENT all used _Z |
Now WXD, T and N |
get_oecd_productivity() |
DSD_PDB@DF_PDB_LV answers HTTP 500 for every query |
Reads DSD_PDB@DF_PDB version 2.0 |
Once the request succeeded, parse_tax() still returned
nothing: all three of its filters used codes the OECD has since renamed.
The institutional sector total is S13, not _T,
and both revenue dimensions use _T rather than
_Z. Verified against Australia, which now reports 27.8 to
29.5 per cent of GDP across 2015 to 2021, matching the published
ratio.
DF_PDB is the full productivity database rather than the
levels extract the package used to read, so the same measure code
appears as a level, a growth rate and an index. Taking it unfiltered
mixed GDP per hour in US dollars with percentage changes, including
negative values. parse_productivity() now selects the
level, PPP-converted, total-economy slice, and takes chain linked volume
rather than current prices: on the current-price basis Australian GDP
per hour rises 38 per cent over 2015 to 2021 against 6 per cent in
volume terms, and that difference is inflation rather than
productivity.
The API refuses further requests after a few dozen in quick
succession, which a test run or a loop over countries reaches easily.
Requests are now throttled to one per second, and 429 and 5xx responses
are explicitly treated as transient so the existing retry applies to
them. The network tests skip rather than fail when the portal is
refusing, via a new expect_oecd() helper, so the suite
stays a useful signal.
get_oecd_trade corrected to
get_oecd_current_account).get_oecd_unemployment() when
requesting all countries.try() to handle transient OECD
API failures gracefully during CRAN checks.tempdir() instead of the user’s
home directory, fixing CRAN policy compliance for \donttest
examples.options(readoecd.cache_dir = ...).get_oecd_cpi() — annual CPI inflation rate,
year-on-year (OECD Prices database).get_oecd_deficit() — general government net
lending/borrowing as % of GDP (NAAG).get_oecd_inequality() — Gini coefficient of
disposable income (OECD IDD).get_oecd_gdp() — annual GDP at current prices
(OECD National Accounts).get_oecd_tax() — total tax revenue as % of GDP
(OECD Revenue Statistics).get_oecd_health() — total health expenditure as %
of GDP (SHA database).get_oecd_education() — total education
expenditure as % of GDP (EAG UOE Finance).get_oecd_productivity() — GDP per hour worked or
per capita (OECD PDB).get_oecd_current_account() — annual current
account balance in USD (OECD BOP).get_oecd_unemployment() — monthly unemployment rates
for all 38 OECD members.list_oecd_countries(),
check_oecd_api(), clear_oecd_cache().