Skip to content

Add stale fallback for domain listing on business registry outage#2916

Open
OlegPhenomenon wants to merge 7 commits into
masterfrom
feature/165-listing-company-codes-stale-fallback
Open

Add stale fallback for domain listing on business registry outage#2916
OlegPhenomenon wants to merge 7 commits into
masterfrom
feature/165-listing-company-codes-stale-fallback

Conversation

@OlegPhenomenon

@OlegPhenomenon OlegPhenomenon commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • New ListingCompanyCodesResolver service: cache-first company codes lookup with bounded stale fallback for the read-only domain listing path
  • New listing-specific scopes (Domain.listing_user_domains, Contact.org_contacts_by_codes) that accept pre-resolved company codes without calling RegistrantUser#companies
  • domains#index now uses the resolver once per request; direct domains are always preserved, company-linked domains degrade gracefully
  • Write paths (registry_locks, contacts, EPP) remain completely unchanged — no stale fallback for mutations

What changes

File Change
app/services/listing_company_codes_resolver.rb New service: cache-first + stale fallback + structured logging
app/models/domain.rb listing_user_domains / listing_user_domains_count scopes
app/models/contact.rb org_contacts_by_codes class method
app/controllers/api/v1/registrant/domains_controller.rb index uses resolver; show unchanged

Test plan

  • test/services/listing_company_codes_resolver_test.rb — 17 tests (cache hit, live success, stale fallback, SOAP fault, cache write failure, ident dash early return, logging)
  • test/models/contact_test.rb — org_contacts_by_codes tests
  • test/models/domain_test.rb — listing scope tests (direct, company-linked, dedupe, admin flag)
  • test/integration/api/v1/registrant/domains_test.rb — 8 integration tests (live success, outage+stale, outage+no cache, SOAP fault, totals, resolver once per request, JSON shape)
  • test/integration/api/v1/registrant/registry_locks_test.rb — negative regression (resolver not used, write path unchanged)

Close internetee/registrant_center#165

…ilable

Domain listing endpoint no longer returns empty results when the
business registry SOAP service is down. A new ListingCompanyCodesResolver
service provides cache-first lookup with bounded stale fallback for
company codes, used exclusively in the read-only domains#index path.
Direct domains are always preserved; company-linked domains degrade
gracefully. Write paths (registry locks, contacts) remain unchanged.

Resolves registrant_center#165
CompanyRegister::Client already caches representation_rights responses
internally via cache_store.fetch with cache_period TTL. The resolver
was duplicating this with its own primary key. Now the resolver only
maintains a stale fallback key — the gem handles primary caching.
Adds registrant user, contacts, and domains for testing the company
codes stale fallback feature via TARA test login (60001019906).
Pre-populates both gem cache and stale cache so company-linked domains
are visible immediately. Includes instructions for simulating outage.
After switching the company_register gem from HTTPI to Net::HTTP adapter,
network-level errors like Net::OpenTimeout bubble up from the SOAP client
without being wrapped into CompanyRegister::NotAvailableError. This caused
domains#index to return 500 instead of falling back to direct domains when
the business registry was unreachable.

Resolver now catches Net::OpenTimeout, Net::ReadTimeout, Errno::ECONNREFUSED,
Errno::EHOSTUNREACH, Errno::ENETUNREACH, Errno::ETIMEDOUT, SocketError and
OpenSSL::SSL::SSLError and treats them the same as NotAvailableError:
fall back to stale cache, log as 'network_error'.
On staging the company_register gem uses the HTTPI adapter, which raises
HTTPI::SSLError / HTTPI::Error for network problems. These were bubbling
up past the resolver's rescue and causing 500 responses.

Resolver now catches HTTPI::Error (when HTTPI is loaded) alongside the
Net::HTTP-era error classes. Added a regression test that raises
HTTPI::SSLError and expects stale fallback.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Business registry failure blocks domain listing for users

2 participants