fix: retry failed cursor page loads

This commit is contained in:
Jonathan Finley 2026-03-13 23:28:49 -04:00
parent 5c3e8559d4
commit f1fe40c3c7
2 changed files with 54 additions and 44 deletions

View file

@ -379,19 +379,8 @@ export default {
let entityPath = this.entityName === 'series-books' ? 'items' : this.entityName let entityPath = this.entityName === 'series-books' ? 'items' : this.entityName
const fullQueryString = this.getFetchQueryString(page) const fullQueryString = this.getFetchQueryString(page)
const payload = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/${entityPath}${fullQueryString}`).catch((error) => {
console.error('failed to fetch items', error)
return null
})
this.isFetchingEntities = false
if (this.pendingReset) {
this.pendingReset = false
this.resetEntities()
return
}
if (payload) {
try { try {
const payload = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/${entityPath}${fullQueryString}`)
const results = Array.isArray(payload.results) ? payload.results : null const results = Array.isArray(payload.results) ? payload.results : null
if (!results) { if (!results) {
throw new Error('Invalid browse payload: missing results array') throw new Error('Invalid browse payload: missing results array')
@ -426,8 +415,13 @@ export default {
this.$eventBus.$emit('bookshelf-total-entities', this.totalEntities) this.$eventBus.$emit('bookshelf-total-entities', this.totalEntities)
} catch (error) { } catch (error) {
console.error(`Failed to process page ${page}`, error) console.error(`Failed to load page ${page}`, error)
return null throw error
} finally {
this.isFetchingEntities = false
if (this.pendingReset) {
this.pendingReset = false
this.resetEntities()
} }
} }
}, },

View file

@ -121,7 +121,7 @@ describe('LazyBookshelf', () => {
}) })
}) })
it('clears progressive loading state when a keyset follow-up chunk fails', () => { it('retries a failed keyset follow-up chunk after the initial load recovers', () => {
const getStub = cy.stub() const getStub = cy.stub()
getStub.onFirstCall().resolves({ getStub.onFirstCall().resolves({
@ -137,12 +137,28 @@ describe('LazyBookshelf', () => {
paginationMode: 'keyset', paginationMode: 'keyset',
isCountDeferred: true isCountDeferred: true
}) })
getStub.onThirdCall().resolves({
results: [{ id: 'item-2', mediaType: 'book', media: { metadata: { title: 'Beta' } } }],
total: 4,
nextCursor: null,
paginationMode: 'keyset',
isCountDeferred: true
})
cy.spy(console, 'error').as('consoleError') cy.spy(console, 'error').as('consoleError')
mountBookshelf(getStub).then(({ wrapper }) => { mountBookshelf(getStub).then(({ wrapper }) => {
cy.wrap(getStub).should('have.been.calledTwice') cy.wrap(getStub).should('have.been.calledTwice')
cy.get('@consoleError').should('have.been.called') cy.get('@consoleError').should('have.been.called')
cy.wrap(null)
.then(() => {
expect(wrapper.vm.pagesLoaded[1]).to.equal(undefined)
return wrapper.vm.loadPage(1)
})
.then(() => {
expect(getStub).to.have.been.calledThrice
expect(wrapper.vm.entities[1].id).to.equal('item-2')
})
cy.wrap(null).then(() => { cy.wrap(null).then(() => {
expect(wrapper.vm.isProgressiveLoading).to.equal(false) expect(wrapper.vm.isProgressiveLoading).to.equal(false)
expect(wrapper.vm.progressiveLoadProgress).to.equal(100) expect(wrapper.vm.progressiveLoadProgress).to.equal(100)