mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-07-08 10:21:38 +00:00
fix: retry failed cursor page loads
This commit is contained in:
parent
5c3e8559d4
commit
f1fe40c3c7
2 changed files with 54 additions and 44 deletions
|
|
@ -379,55 +379,49 @@ 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) => {
|
try {
|
||||||
console.error('failed to fetch items', error)
|
const payload = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/${entityPath}${fullQueryString}`)
|
||||||
return null
|
const results = Array.isArray(payload.results) ? payload.results : null
|
||||||
})
|
if (!results) {
|
||||||
|
throw new Error('Invalid browse payload: missing results array')
|
||||||
|
}
|
||||||
|
|
||||||
this.isFetchingEntities = false
|
this.paginationMode = payload.paginationMode || this.paginationMode
|
||||||
if (this.pendingReset) {
|
this.nextCursor = payload.nextCursor || null
|
||||||
this.pendingReset = false
|
this.isCountDeferred = !!payload.isCountDeferred
|
||||||
this.resetEntities()
|
|
||||||
return
|
if (this.paginationMode === 'keyset') {
|
||||||
}
|
if (this.nextCursor) {
|
||||||
if (payload) {
|
this.pageCursors[page + 1] = this.nextCursor
|
||||||
try {
|
} else {
|
||||||
const results = Array.isArray(payload.results) ? payload.results : null
|
delete this.pageCursors[page + 1]
|
||||||
if (!results) {
|
|
||||||
throw new Error('Invalid browse payload: missing results array')
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.paginationMode = payload.paginationMode || this.paginationMode
|
if (!this.initialized) {
|
||||||
this.nextCursor = payload.nextCursor || null
|
this.initialized = true
|
||||||
this.isCountDeferred = !!payload.isCountDeferred
|
this.totalEntities = payload.total
|
||||||
|
this.totalShelves = Math.ceil(this.totalEntities / this.entitiesPerShelf)
|
||||||
|
this.entities = new Array(this.totalEntities)
|
||||||
|
}
|
||||||
|
|
||||||
if (this.paginationMode === 'keyset') {
|
for (let i = 0; i < results.length; i++) {
|
||||||
if (this.nextCursor) {
|
const index = i + startIndex
|
||||||
this.pageCursors[page + 1] = this.nextCursor
|
this.entities[index] = results[i]
|
||||||
} else {
|
if (this.entityComponentRefs[index]) {
|
||||||
delete this.pageCursors[page + 1]
|
this.entityComponentRefs[index].setEntity(this.entities[index])
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.initialized) {
|
this.$eventBus.$emit('bookshelf-total-entities', this.totalEntities)
|
||||||
this.initialized = true
|
} catch (error) {
|
||||||
this.totalEntities = payload.total
|
console.error(`Failed to load page ${page}`, error)
|
||||||
this.totalShelves = Math.ceil(this.totalEntities / this.entitiesPerShelf)
|
throw error
|
||||||
this.entities = new Array(this.totalEntities)
|
} finally {
|
||||||
}
|
this.isFetchingEntities = false
|
||||||
|
if (this.pendingReset) {
|
||||||
for (let i = 0; i < results.length; i++) {
|
this.pendingReset = false
|
||||||
const index = i + startIndex
|
this.resetEntities()
|
||||||
this.entities[index] = results[i]
|
|
||||||
if (this.entityComponentRefs[index]) {
|
|
||||||
this.entityComponentRefs[index].setEntity(this.entities[index])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$eventBus.$emit('bookshelf-total-entities', this.totalEntities)
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Failed to process page ${page}`, error)
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue