Skip to content

Commit 8936b8d

Browse files
committed
fix(ssr): properly handle errors in async component
fix #6778
1 parent 86e4d75 commit 8936b8d

File tree

4 files changed

+30
-10
lines changed

4 files changed

+30
-10
lines changed

src/server/create-renderer.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,15 @@ export function createRenderer ({
7878
return false
7979
}, cb)
8080
try {
81-
render(component, write, context, () => {
81+
render(component, write, context, err => {
8282
if (template) {
8383
result = templateRenderer.renderSync(result, context)
8484
}
85-
cb(null, result)
85+
if (err) {
86+
cb(err)
87+
} else {
88+
cb(null, result)
89+
}
8690
})
8791
} catch (e) {
8892
cb(e)

src/server/render-context.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class RenderContext {
2626
write: (text: string, next: Function) => void;
2727
renderNode: (node: VNode, isRoot: boolean, context: RenderContext) => void;
2828
next: () => void;
29-
done: () => void;
29+
done: (err: ?Error) => void;
3030

3131
modules: Array<(node: VNode) => ?string>;
3232
directives: Object;

src/server/render.js

+4-7
Original file line numberDiff line numberDiff line change
@@ -193,21 +193,18 @@ function renderAsyncComponent (node, isRoot, context) {
193193
if (resolvedNode) {
194194
renderComponent(resolvedNode, isRoot, context)
195195
} else {
196-
reject()
196+
// invalid component, but this does not throw on the client
197+
// so render empty comment node
198+
context.write(`<!---->`, context.next)
197199
}
198200
}
199201

200-
const reject = err => {
201-
console.error(`[vue-server-renderer] error when rendering async component:\n`)
202-
if (err) console.error(err.stack)
203-
context.write(`<!--${node.text}-->`, context.next)
204-
}
205-
206202
if (factory.resolved) {
207203
resolve(factory.resolved)
208204
return
209205
}
210206

207+
const reject = context.done
211208
let res
212209
try {
213210
res = factory(resolve, reject)

test/ssr/ssr-string.spec.js

+19
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,25 @@ describe('SSR: renderToString', () => {
575575
})
576576
})
577577

578+
it('should catch async component error', done => {
579+
Vue.config.silent = true
580+
renderToString(new Vue({
581+
template: '<test-async></test-async>',
582+
components: {
583+
testAsync: () => Promise.resolve({
584+
render () {
585+
throw new Error('foo')
586+
}
587+
})
588+
}
589+
}), (err, result) => {
590+
Vue.config.silent = false
591+
expect(err).toBeTruthy()
592+
expect(result).toBeUndefined()
593+
done()
594+
})
595+
})
596+
578597
it('everything together', done => {
579598
renderVmWithOptions({
580599
template: `

0 commit comments

Comments
 (0)