diff --git a/packages/cli/package.json b/packages/cli/package.json index 946945b00c..5f9142ca90 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -20,6 +20,7 @@ "fsevents": "~2.3.2" }, "devDependencies": { + "@nuxt/design": "0.0.4", "@nuxt/kit": "^0.6.4", "@types/clear": "^0", "@types/debounce-promise": "^3", diff --git a/packages/cli/src/commands/dev.ts b/packages/cli/src/commands/dev.ts index e2fb99789c..dfcbbcb289 100644 --- a/packages/cli/src/commands/dev.ts +++ b/packages/cli/src/commands/dev.ts @@ -22,7 +22,7 @@ export async function invoke (args) { const load = async (isRestart) => { try { const message = `${isRestart ? 'Restarting' : 'Starting'} nuxt...` - server.setApp(createLoadingHandler(message, 1)) + server.setApp(createLoadingHandler(message)) if (isRestart) { console.log(message) } diff --git a/packages/cli/src/utils/server.ts b/packages/cli/src/utils/server.ts index 50098e0cb7..bed996b5da 100644 --- a/packages/cli/src/utils/server.ts +++ b/packages/cli/src/utils/server.ts @@ -1,7 +1,8 @@ import type { RequestListener } from 'http' +import { loading } from '@nuxt/design' export function createServer () { - const listener = createDynamicFunction(createLoadingHandler('Loading...', 1)) + const listener = createDynamicFunction(createLoadingHandler('Loading...')) async function listen (opts) { const { listen } = await import('listhen') @@ -14,12 +15,11 @@ export function createServer () { } } -export function createLoadingHandler (message: string, retryAfter = 60): RequestListener { +export function createLoadingHandler (message: string): RequestListener { return (_req, res) => { res.setHeader('Content-Type', 'text/html; charset=UTF-8') res.statusCode = 503 /* Service Unavailable */ - res.setHeader('Retry-After', retryAfter) - res.end(`
${message}`) + res.end(loading({ loading: message })) } } diff --git a/packages/nitro/package.json b/packages/nitro/package.json index 6d56fdfa6a..fed8a1c899 100644 --- a/packages/nitro/package.json +++ b/packages/nitro/package.json @@ -15,6 +15,7 @@ "dependencies": { "@cloudflare/kv-asset-handler": "^0.1.3", "@netlify/functions": "^0.7.2", + "@nuxt/design": "0.0.4", "@nuxt/devalue": "^2.0.0", "@nuxt/kit": "^0.6.4", "@rollup/plugin-alias": "^3.1.2", diff --git a/packages/nitro/src/runtime/app/render.ts b/packages/nitro/src/runtime/app/render.ts index 6756ca18f2..7f666789ab 100644 --- a/packages/nitro/src/runtime/app/render.ts +++ b/packages/nitro/src/runtime/app/render.ts @@ -47,6 +47,11 @@ export async function renderMiddleware (req, res) { const renderer = await loadRenderer() const rendered = await renderer.renderToString(ssrContext) + // Handle errors + if (ssrContext.error) { + throw ssrContext.error + } + if (ssrContext.nuxt.hooks) { await ssrContext.nuxt.hooks.callHook('app:rendered') } diff --git a/packages/nitro/src/runtime/server/error.ts b/packages/nitro/src/runtime/server/error.ts index 155325d125..e1b98f984d 100644 --- a/packages/nitro/src/runtime/server/error.ts +++ b/packages/nitro/src/runtime/server/error.ts @@ -1,8 +1,15 @@ // import ansiHTML from 'ansi-html' +import type { IncomingMessage, ServerResponse } from 'http' +import { error500, error404, errorDev } from '@nuxt/design' const cwd = process.cwd() -// TODO: Handle process.env.DEBUG -export function handleError (error, req, res) { +const hasReqHeader = (req, header, includes) => req.headers[header] && req.headers[header].toLowerCase().includes(includes) + +const isDev = process.env.NODE_ENV === 'development' + +export function handleError (error, req: IncomingMessage, res: ServerResponse) { + const isJsonRequest = hasReqHeader(req, 'accept', 'application/json') || hasReqHeader(req, 'user-agent', 'curl/') || hasReqHeader(req, 'user-agent', 'httpie/') + const stack = (error.stack || '') .split('\n') .splice(1) @@ -21,47 +28,35 @@ export function handleError (error, req, res) { } }) - console.error(error.message + '\n' + stack.map(l => ' ' + l.text).join(' \n')) + const is404 = error.statusCode === 404 - const html = ` - - - - -${stack.map(i =>
- `${i.text}`
- ).join('\n')
- }
- ${stack.map(i => `${i.text}`).join('\n')}
+ `
+ : ''
+ }
res.statusCode = error.statusCode || 500
- res.statusMessage = error.statusMessage || 'Internal Error'
+ res.statusMessage = error.statusMessage || 'Internal Server Error'
+
+ // Console output
+ if (!is404) {
+ console.error(error.message + '\n' + stack.map(l => ' ' + l.text).join(' \n'))
+ }
+
+ // JSON response
+ if (isJsonRequest) {
+ res.setHeader('Content-Type', 'application/json')
+ return res.end(JSON.stringify(errorObject))
+ }
+
+ // HTML response
+ const errorTemplate = is404 ? error404 : (isDev ? errorDev : error500)
+ const html = errorTemplate(errorObject)
res.end(html)
}
diff --git a/packages/nitro/src/server/dev.ts b/packages/nitro/src/server/dev.ts
index 570bf1c127..2b856a54eb 100644
--- a/packages/nitro/src/server/dev.ts
+++ b/packages/nitro/src/server/dev.ts
@@ -1,5 +1,6 @@
import { Worker } from 'worker_threads'
+import { loading as loadingTemplate } from '@nuxt/design'
import chokidar, { FSWatcher } from 'chokidar'
import debounce from 'debounce'
import { stat } from 'fs-extra'
@@ -74,7 +75,7 @@ export function createDevServer (nitroContext: NitroContext) {
})
} else {
res.setHeader('Content-Type', 'text/html; charset=UTF-8')
- res.end('...')
+ res.end(loadingTemplate({}))
}
})
diff --git a/packages/pages/src/module.ts b/packages/pages/src/module.ts
index 153f33380b..5bb7f518be 100644
--- a/packages/pages/src/module.ts
+++ b/packages/pages/src/module.ts
@@ -36,17 +36,6 @@ export default defineNuxtModule({
// Resolve routes
const routes = await resolvePagesRoutes(nuxt)
- // Add 404 page is not added
- const page404 = routes.find(route => route.name === '404')
- if (!page404) {
- routes.push({
- name: '404',
- path: '/:catchAll(.*)*',
- file: resolve(runtimeDir, '404.vue'),
- children: []
- })
- }
-
// Add routes.js
app.templates.push({
path: 'routes.js',
diff --git a/packages/pages/src/runtime/404.vue b/packages/pages/src/runtime/404.vue
deleted file mode 100644
index dd196f5823..0000000000
--- a/packages/pages/src/runtime/404.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-
-