Skip to content

Fix <ds-search> rendering an empty page when the search configuration request fails - #6111

Open
naomigassler wants to merge 1 commit into
DSpace:mainfrom
naomigassler:fix/search-blank-page-on-config-failure
Open

Fix <ds-search> rendering an empty page when the search configuration request fails#6111
naomigassler wants to merge 1 commit into
DSpace:mainfrom
naomigassler:fix/search-blank-page-on-config-failure

Conversation

@naomigassler

Copy link
Copy Markdown

When the search-configuration request fails, <ds-search> renders nothing at
all
 — no results, no empty state, and no error. The page looks like an empty
repository.

getConfigurationSearchConfig() pipes through getAllSucceededRemoteDataPayload(),
so a failed request never emits. combineLatest therefore never fires,
initialized$ stays false, and the whole <ds-search> template is skipped —
including the ds-error block that search-results.component already has. The
error handling is present; it is simply never constructed.

Measured on main (3d59ea31e) with only the search-configuration request
failing (500 on /server/api/discover/search?configuration=*), everything else
healthy:

                    before    after
ds-search-form:          0        1
ds-search-results:       0        2
main text length:       38     1863

With the results request failing as well — the case that should surface an error:

                    before    after
ds-error in main:        0        1     ("Error fetching search results")
main text length:       38      312

(38 characters is the submission drop-zone, which sits outside <ds-search>.)

Note that stopping the whole backend does not reproduce this on main:
ServerCheckGuard redirects to /500 before <ds-search> renders. The
configuration request has to fail while the root endpoint is still reachable.

This is not specific to one page. <ds-search> backs 6 routes, and whether
you see the bug depends only on whether that configuration is already cached:

  • /search usually survives, because the homepage has already cached the default
    configuration.
  • /mydspace and /access-control/bulk-access were both in a cold-cache state
    and both blanked out.

So the trigger is any search config request that fails from a cold cache — an
outage is simply the easiest way to produce one.

Fix

21 lines in one file. No new i18n key; reuses the existing ds-error component
and the existing message. /mydspace now shows "Error fetching search results"
instead of a blank page.

Verification

Run against main at 3d59ea31e:

check | result -- | -- /mydspace, search config failing | error rendered; main text 38 → 312 chars healthy loads × 10 | 0/10 spurious error states (609 samples at 150 ms) unit tests | 40/40 pass, + 2 new covering error-vs-empty npm run lint | clean — "All files pass linting" npm run check-circ-deps | "No circular dependency found!" npm run build:prod | succeeds

Screenshots: blank page before, error state after, and the ordinary
"Your search returned no results" empty state for comparison — the error and empty
states are unmistakably distinct.

<screenshots: V1-mydspace-down.png, V5-mydspace-down.png, V5-mydspace-empty-state.png>

Known limitation

Some installations report a 400 on this endpoint when the search fires before
authentication is attached (An anonymous user cannot perform a workspace or workflow search). Upstream already treats that as "no results" via showError()'s
statusCode !== 400 exemption, and this change leaves that exemption intact. Our
stack does not reproduce that 400, so we have shown that this change does not
introduce a spurious error state — not that it handles that case correctly.
Confirmation from someone who can reproduce it would be welcome.

Before: upstream main with the search-configuration request returning 500
(results request also failing). /mydspace renders an empty content area — no
results, no empty state, no error. ds-search-form, ds-search-results and
ds-error are all absent from the DOM; the only content is the submission
drop-zone, which sits outside <ds-search>.V5-before-config-500

After: same code path with this fix applied, same injected 500s. The component
initialises, so ds-search-results is created and renders its existing error
state — "Error fetching search results".

Two details in this image are worth naming rather than leaving to be spotted.
The filter label search.filters.filter.owningcollection.head is untranslated:
that key is absent from upstream en.json5 (grep -c → 0) and appears on
healthy /mydspace loads on unmodified main too — it is visible here only
because the fix makes the sidebar render at all. The Sort By control is
empty because its options come from the search configuration, which is the
request that failed. Neither is introduced by this change, and neither is
claimed to be fixed by it: the claim is an error message instead of an empty
page, not a fully functional page in a state where the configuration is
unavailable.
V5-after-config-500

For comparison: this fix applied, healthy backend, a configuration with no
results ("Workflow tasks"). The ordinary empty state — "Your search returned no
results" — is still clearly distinct from the error state above.
V5-after-empty-state

…figuration request fails

SearchComponent derives searchSortOptions$ from
SearchConfigurationService.getConfigurationSearchConfig(), which pipes through
getAllSucceededRemoteDataPayload(). When that request fails the observable never
emits, so the combineLatest in ngOnInit never fires and initialized$ stays
false. Both @if branches in search.component.html are gated on initialized$, so
the whole template is skipped and the page renders empty: not even
ds-search-results, which already knows how to render an error, is created.

Treat a failed configuration as "no sort options" so the component still
initializes. PaginationService.getCurrentSort() already falls back to its
default when handed an empty default sort, so the empty list is safe, and the
outcome of the results request (results, empty state, or error) is what the
user sees.

This affects every ds-search instance whose configuration is not already
cached. /search normally survives because the homepage caches the 'default'
configuration, but /mydspace, /access-control/bulk-access and the item and
collection mappers request their own configurations only on those pages, so a
failure there leaves a blank page.

Adds specs asserting the component still initializes, and still requests
results, when the search configuration request fails.
@lgeggleston lgeggleston changed the title Fix <ds-search> rendering an empty page when the search configuration request failsShow search results error instead of a blank page when the search con… Fix <ds-search> rendering an empty page when the search configuration request fails Aug 21, 2026
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.

1 participant