mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-18 14:41:25 +00:00
feat: call global vue errorHandler in fetch and asyncData (#3652)
resolve #3335
This commit is contained in:
parent
823c298046
commit
6aaf839d54
@ -13,7 +13,9 @@ import {
|
|||||||
promisify,
|
promisify,
|
||||||
getLocation,
|
getLocation,
|
||||||
compile,
|
compile,
|
||||||
getQueryDiff
|
getQueryDiff,
|
||||||
|
globalHandleError,
|
||||||
|
empty
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
|
||||||
const noopData = () => { return {} }
|
const noopData = () => { return {} }
|
||||||
@ -340,14 +342,16 @@ async function render (to, from, next) {
|
|||||||
// Call asyncData(context)
|
// Call asyncData(context)
|
||||||
if (hasAsyncData) {
|
if (hasAsyncData) {
|
||||||
const promise = promisify(Component.options.asyncData, app.context)
|
const promise = promisify(Component.options.asyncData, app.context)
|
||||||
.then((asyncDataResult) => {
|
.then((asyncDataResult) => {
|
||||||
applyAsyncData(Component, asyncDataResult)
|
applyAsyncData(Component, asyncDataResult)
|
||||||
<% if (loading) { %>
|
<% if (loading) { %>
|
||||||
if(this.$loading.increase) {
|
if(this.$loading.increase) {
|
||||||
this.$loading.increase(loadingIncrease)
|
this.$loading.increase(loadingIncrease)
|
||||||
}
|
}
|
||||||
<% } %>
|
<% } %>
|
||||||
})
|
})
|
||||||
|
// error will be handled in try catch
|
||||||
|
.catch(empty)
|
||||||
promises.push(promise)
|
promises.push(promise)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -356,18 +360,20 @@ async function render (to, from, next) {
|
|||||||
|
|
||||||
// Call fetch(context)
|
// Call fetch(context)
|
||||||
if (hasFetch) {
|
if (hasFetch) {
|
||||||
let p = Component.options.fetch(app.context)
|
let p = Component.options.fetch(app.context)
|
||||||
if (!p || (!(p instanceof Promise) && (typeof p.then !== 'function'))) {
|
if (!p || (!(p instanceof Promise) && (typeof p.then !== 'function'))) {
|
||||||
p = Promise.resolve(p)
|
p = Promise.resolve(p)
|
||||||
}
|
|
||||||
p.then((fetchResult) => {
|
|
||||||
<% if (loading) { %>
|
|
||||||
if (this.$loading.increase) {
|
|
||||||
this.$loading.increase(loadingIncrease)
|
|
||||||
}
|
}
|
||||||
<% } %>
|
p.then((fetchResult) => {
|
||||||
})
|
<% if (loading) { %>
|
||||||
promises.push(p)
|
if (this.$loading.increase) {
|
||||||
|
this.$loading.increase(loadingIncrease)
|
||||||
|
}
|
||||||
|
<% } %>
|
||||||
|
})
|
||||||
|
// error will be handled in try catch
|
||||||
|
.catch(empty)
|
||||||
|
promises.push(p)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Promise.all(promises)
|
return Promise.all(promises)
|
||||||
@ -391,6 +397,8 @@ async function render (to, from, next) {
|
|||||||
const errorResponseStatus = (error.response && error.response.status)
|
const errorResponseStatus = (error.response && error.response.status)
|
||||||
error.statusCode = error.statusCode || error.status || errorResponseStatus || 500
|
error.statusCode = error.statusCode || error.status || errorResponseStatus || 500
|
||||||
|
|
||||||
|
globalHandleError(error)
|
||||||
|
|
||||||
// Load error layout
|
// Load error layout
|
||||||
let layout = NuxtError.layout
|
let layout = NuxtError.layout
|
||||||
if (typeof layout === 'function') {
|
if (typeof layout === 'function') {
|
||||||
|
@ -11,6 +11,14 @@ if (process.browser) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function empty() {}
|
||||||
|
|
||||||
|
export function globalHandleError(error) {
|
||||||
|
if (Vue.config.errorHandler) {
|
||||||
|
Vue.config.errorHandler(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function applyAsyncData(Component, asyncData) {
|
export function applyAsyncData(Component, asyncData) {
|
||||||
const ComponentData = Component.options.data || noopData
|
const ComponentData = Component.options.data || noopData
|
||||||
// Prevent calling this method for each request on SSR context
|
// Prevent calling this method for each request on SSR context
|
||||||
|
5
test/fixtures/spa/nuxt.config.js
vendored
5
test/fixtures/spa/nuxt.config.js
vendored
@ -5,5 +5,8 @@ export default {
|
|||||||
http2: {
|
http2: {
|
||||||
push: true
|
push: true
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
plugins: [
|
||||||
|
'~/plugins/error.js'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
8
test/fixtures/spa/pages/error-handler.vue
vendored
Normal file
8
test/fixtures/spa/pages/error-handler.vue
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
fetch() {
|
||||||
|
throw Error('spa test error!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
5
test/fixtures/spa/plugins/error.js
vendored
Normal file
5
test/fixtures/spa/plugins/error.js
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import Vue from 'vue'
|
||||||
|
|
||||||
|
Vue.config.errorHandler = function () {
|
||||||
|
document.body.appendChild(document.createTextNode('error handler triggered'))
|
||||||
|
}
|
@ -43,6 +43,12 @@ describe('spa', () => {
|
|||||||
expect(html).toMatch('<h1>Test: updated</h1>')
|
expect(html).toMatch('<h1>Test: updated</h1>')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('/error-handler', async () => {
|
||||||
|
await renderRoute('/error-handler')
|
||||||
|
const { html } = await renderRoute('/error-handler')
|
||||||
|
expect(html).toMatch('error handler triggered')
|
||||||
|
})
|
||||||
|
|
||||||
test('/_nuxt/ (access publicPath in spa mode)', async () => {
|
test('/_nuxt/ (access publicPath in spa mode)', async () => {
|
||||||
await expect(renderRoute('/_nuxt/')).rejects.toMatchObject({
|
await expect(renderRoute('/_nuxt/')).rejects.toMatchObject({
|
||||||
response: {
|
response: {
|
||||||
|
Loading…
Reference in New Issue
Block a user