Skip to content

Commit

Permalink
Reload page if resource fetch fails, and appears online (#2996)
Browse files Browse the repository at this point in the history
* Reload page if resource fetch fails, and appears online (#2954, #1807)

* Track failed prefetched paths and resources to trigger reload sooner

* Remove index.js

* format
  • Loading branch information
lsirivong authored and KyleAMathews committed Dec 14, 2017
1 parent ee117a8 commit 54d255a
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 5 deletions.
9 changes: 8 additions & 1 deletion packages/gatsby-source-contentful/src/__tests__/normalize.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,14 @@ let resolvable
let foreignReferenceMap
const conflictFieldPrefix = `contentful_test`
// restrictedNodeFields from here https://www.gatsbyjs.org/docs/node-interface/
const restrictedNodeFields = [`id`, `children`, `contentful_id`, `parent`, `fields`, `internal`]
const restrictedNodeFields = [
`id`,
`children`,
`contentful_id`,
`parent`,
`fields`,
`internal`,
]

describe(`Process contentful data`, () => {
it(`builds entry list`, () => {
Expand Down
71 changes: 67 additions & 4 deletions packages/gatsby/cache-dir/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ let resourcesCount = {}
const preferDefault = m => (m && m.default) || m
let prefetcher
let inInitialRender = true
let fetchHistory = []
const failedPaths = {}
const failedResources = {}
const MAX_HISTORY = 5

// Prefetcher logic
if (process.env.NODE_ENV === `production`) {
Expand Down Expand Up @@ -78,6 +82,16 @@ const fetchResource = (resourceName, cb = () => {}) => {
// Download the resource
resourceFunction((err, executeChunk) => {
resourceStrCache[resourceName] = executeChunk
fetchHistory.push({
resource: resourceName,
succeeded: !err,
})

if (!failedResources[resourceName]) {
failedResources[resourceName] = err
}

fetchHistory = fetchHistory.slice(-MAX_HISTORY)
cb(err, executeChunk)
})
}
Expand All @@ -88,6 +102,10 @@ const getResourceModule = (resourceName, cb) => {
process.nextTick(() => {
cb(null, resourceCache[resourceName])
})
} else if (failedResources[resourceName]) {
process.nextTick(() => {
cb(failedResources[resourceName])
})
} else {
fetchResource(resourceName, (err, executeChunk) => {
if (err) {
Expand All @@ -101,6 +119,32 @@ const getResourceModule = (resourceName, cb) => {
}
}

const appearsOnLine = () => {
const isOnLine = navigator.onLine
if (typeof isOnLine === `boolean`) {
return isOnLine
}

// If no navigator.onLine support assume onLine if any of last N fetches succeeded
const succeededFetch = fetchHistory.find(entry => entry.succeeded)
return !!succeededFetch
}

const handleResourceLoadError = (path, message) => {
console.log(message)

if (!failedPaths[path]) {
failedPaths[path] = message
}

if (
appearsOnLine() &&
window.location.pathname.replace(/\/$/g, ``) !== path.replace(/\/$/g, ``)
) {
window.location.pathname = path
}
}

let mountOrder = 1
const queue = {
empty: () => {
Expand Down Expand Up @@ -253,10 +297,20 @@ const queue = {
return pageResources
// Production code path
} else {
if (failedPaths[path]) {
handleResourceLoadError(
path,
`Previously detected load failure for "${path}"`
)

return cb()
}

const page = findPage(path)

if (!page) {
console.log(`A page wasn't found for "${path}"`)
handleResourceLoadError(path, `A page wasn't found for "${path}"`)

return cb()
}

Expand Down Expand Up @@ -297,14 +351,20 @@ const queue = {
}
getResourceModule(page.componentChunkName, (err, c) => {
if (err) {
console.log(`Loading the component for ${page.path} failed`)
handleResourceLoadError(
page.path,
`Loading the component for ${page.path} failed`
)
}
component = c
done()
})
getResourceModule(page.jsonName, (err, j) => {
if (err) {
console.log(`Loading the JSON for ${page.path} failed`)
handleResourceLoadError(
page.path,
`Loading the JSON for ${page.path} failed`
)
}
json = j
done()
Expand All @@ -313,7 +373,10 @@ const queue = {
page.layoutComponentChunkName &&
getResourceModule(page.layout, (err, l) => {
if (err) {
console.log(`Loading the Layout for ${page.path} failed`)
handleResourceLoadError(
page.path,
`Loading the Layout for ${page.path} failed`
)
}
layout = l
done()
Expand Down

0 comments on commit 54d255a

Please sign in to comment.