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

@naomigassler naomigassler commented Aug 21, 2026

Copy link
Copy Markdown

This PR was developed with the help of an LLM. I also relied on an LLM to write the description below.


References

_No issue ticket — this was found while investigating #5936 and is filed on its own merits.


Description

<ds-search> renders nothing at all — no search form, no results, no empty state and no error — when its search-configuration request fails. The page looks like an empty repository. This PR lets the component initialise so its existing error handling can run.


Instructions for Reviewers

getConfigurationSearchConfig() pipes through getAllSucceededRemoteDataPayload(), so a failed configuration 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.

List of changes in this PR:

  • search.component.ts — initialise the component when the search-configuration request fails, falling back to empty sort options, so the existing error and empty states can render.
  • search.component.spec.ts — two specs covering error-versus-empty.

How to test

1. Unit specs — no backend, no configuration required.

npm test

The two added specs in search.component.spec.ts cover the case directly.

2. In a browser. This reproduces on unmodified main; the patch is not needed to see the bug.

  1. Log in to any DSpace instance.
  2. Go to /mydspace.
    Not /search/search does not issue this request at all, because the homepage has already cached the default configuration. /mydspace uses workspace, which has not been cached. /access-control/bulk-access also reproduces it.
  3. DevTools → Network → tick Enable request blocking, add the pattern:
    *discover/search?configuration=*
    ⚠ Use exactly that pattern. */discover/search* also blocks the HAL
    endpoint-discovery request, which produces a different failure that
    demonstrates nothing.
  4. Reload.

Before this PR: the content area is empty — no search form, no results, no
empty state, no error. Only the submission drag-and-drop zone remains, because that sits outside <ds-search>. The Network panel shows no
discover/search/objects request at all
: the component never gets far enough to ask for results.

After this PR: the page renders and is usable — though with an empty sort
dropdown, and results in the fallback dc.title,ASC order rather than the
configured lastModified,DESC, because only the configuration request was blocked and the results request still succeeds.

To see the error state, add a second blocking pattern
*discover/search/objects*. You then get "Error fetching search results"
instead of a blank page.

Known limitation, and a question for reviewers

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 PR 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.

Separately: when only the configuration request fails, this PR substitutes defaults silently — the sort order changes and the sort dropdown is empty, with nothing saying so. It may be better to render the error alongside the results rather than
degrading quietly. I do not have a settled view and would welcome yours.


Checklist

  • My PR is created against the main branch of code.
  • My PR is small in size — 44 insertions, 3 deletions, across 2 files.
  • My PR follows all coding best practices based on the Code Conventions Guide.
  • My PR passes ESLint validation using npm run lint — full-repo clean.
  • My PR doesn't introduce circular dependencies — verified via npm run check-circ-deps.
  • My PR includes TypeDoc comments for all new or modified public methods and classes. _
  • My PR passes all specs/tests and includes new/updated specs — 40/40 plus 2 new specs.
  • My PR aligns with Accessibility guidelines. _
  • My PR uses i18n keys instead of hardcoded English text — no new key; reuses the existing ds-error component and message.
  • My PR includes details on how to test it — see above.
  • My PR does not include new libraries/dependencies.
  • My PR does not include new features or configurations.
  • My PR links an issue ticket — none exists; see References.

…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
@tinsch

tinsch commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

@naomigassler could you please provide a self written short text that outlines

  • what this PR is attempting to fix
  • how we can reproduce and test it

@lgeggleston

Copy link
Copy Markdown
Contributor

Hi @naomigassler, since this PR seems to have spun off from #5936 which was closed and based on your comment there, I lean towards closing this as well.

However, if it stands separately from 5936 and you feel strongly about moving it forward, it would need a clear PR description with testing steps as @tinsch describes, and should also use the PR template and checklist before this could be reviewed.

@naomigassler

naomigassler commented Aug 26, 2026

Copy link
Copy Markdown
Author

Hi @lgeggleston and @tinsch,

After the resolution of #5936 I have looked into this patch more deeply. Here is what this patch is trying to accomplish. If for some reason (network glitch, etc) the search configuration request initiated by the user fails to reach the backend, there is currently no notification for the user. The search simply shows no results. This is particularly problematic when looking at /mydspace. The user might be led to believe that there are no items at all in the queue, and nothing is telling them that reloading the search would reveal what is there.

This addresses specifically the configuration request. If the results request fails, existing code already renders "Error fetching search results".

This situation can easily be reproduced as follows (it doesn't need #6111 to be implemented):

  1. Log in to any DSpace instance.
  2. Go to /mydspace. (NOT /search — /search does not issue this request at all, because the homepage has already cached the default configuration. /mydspace uses workspace, which has not been cached.)
  3. Open DevTools → Network → tick "Enable request blocking", and add the pattern: *discover/search?configuration=*
  4. Reload the page.

Before the fix: the content area is empty — no search form, no results, no empty state, no error message. Only the submission drag-and-drop zone remains, because that sits outside <ds-search>.

After the fix: the page renders and is usable, but with an empty sort dropdown, and results come back in the fallback dc.title,ASC order rather than the configured default — because only the configuration request was blocked and the results request still succeeds. (The patch substitutes the result of the missing configuration with default values.)

To see the error state instead, add a second pattern *discover/search/objects* — you then get "Error fetching search results" rather than a blank page.

The PR also carries two unit specs, so this can be checked with a checkout and npm test.

One thing to decide on and possible change: when the configuration request fails, the patch substitutes defaults silently. The sort order changes and the sort dropdown is empty, but nothing says so. It may be better to render the error alongside the results rather than quietly degrading the /mydspace page.

I updated the PR description with the testing steps using the PR template and checklist.

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.

3 participants