Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: early return on closed server only for warmup #16216

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions packages/vite/src/node/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import { getEnvFilesForMode } from '../env'
import type { FetchResult } from '../../runtime/types'
import { ssrFetchModule } from '../ssr/ssrFetchModule'
import type { PluginContainer } from './pluginContainer'
import { ERR_CLOSED_SERVER, createPluginContainer } from './pluginContainer'
import { createPluginContainer } from './pluginContainer'
import type { WebSocketServer } from './ws'
import { createWebSocketServer } from './ws'
import { baseMiddleware } from './middlewares/base'
Expand Down Expand Up @@ -512,20 +512,24 @@ export async function _createServer(
return transformRequest(url, server, options)
},
async warmupRequest(url, options) {
await transformRequest(url, server, options).catch((e) => {
if (
e?.code === ERR_OUTDATED_OPTIMIZED_DEP ||
e?.code === ERR_CLOSED_SERVER
) {
// these are expected errors
return
}
// Unexpected error, log the issue but avoid an unhandled exception
server.config.logger.error(`Pre-transform error: ${e.message}`, {
error: e,
timestamp: true,
})
})
if (server._restartPromise) {
// The server is restarting, avoid warming up this request as it won't be used
// and it will trigger the processing of other requests
return
}
await transformRequest(url, server, { ...options, warmup: true }).catch(
(e) => {
if (e?.code === ERR_OUTDATED_OPTIMIZED_DEP) {
// expected error
return
}
// Unexpected error, log the issue but avoid an unhandled exception
server.config.logger.error(`Pre-transform error: ${e.message}`, {
error: e,
timestamp: true,
})
},
)
},
transformIndexHtml(url, html, originalUrl) {
return devHtmlTransformFn(server, url, html, originalUrl)
Expand Down
16 changes: 0 additions & 16 deletions packages/vite/src/node/server/middlewares/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import {
ERR_OPTIMIZE_DEPS_PROCESSING_ERROR,
ERR_OUTDATED_OPTIMIZED_DEP,
} from '../../plugins/optimizedDeps'
import { ERR_CLOSED_SERVER } from '../pluginContainer'
import { getDepsOptimizer } from '../../optimizer'
import { cleanUrl, unwrapId, withTrailingSlash } from '../../../shared/utils'
import { NULL_BYTE_PLACEHOLDER } from '../../../shared/constants'
Expand Down Expand Up @@ -239,21 +238,6 @@ export function transformMiddleware(
// error but a normal part of the missing deps discovery flow
return
}
if (e?.code === ERR_CLOSED_SERVER) {
// Skip if response has already been sent
if (!res.writableEnded) {
res.statusCode = 504 // status code request timeout
res.statusMessage = 'Outdated Request'
res.end()
}
// We don't need to log an error in this case, the request
// is outdated because new dependencies were discovered and
// the new pre-bundle dependencies have changed.
// A full-page reload has been issued, and these old requests
// can't be properly fulfilled. This isn't an unexpected
// error but a normal part of the missing deps discovery flow
return
}
if (e?.code === ERR_FILE_NOT_FOUND_IN_OPTIMIZED_DEP_DIR) {
// Skip if response has already been sent
if (!res.writableEnded) {
Expand Down
16 changes: 0 additions & 16 deletions packages/vite/src/node/server/pluginContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,18 +84,6 @@ import type { ModuleGraph, ModuleNode } from './moduleGraph'

const noop = () => {}

export const ERR_CLOSED_SERVER = 'ERR_CLOSED_SERVER'

export function throwClosedServerError(): never {
const err: any = new Error(
'The server is being restarted or closed. Request is outdated',
)
err.code = ERR_CLOSED_SERVER
// This error will be caught by the transform middleware that will
// send a 504 status code request timeout
throw err
}

export interface PluginContainerOptions {
cwd?: string
output?: OutputOptions
Expand Down Expand Up @@ -642,7 +630,6 @@ export async function createPluginContainer(
options: await (async () => {
let options = rollupOptions
for (const optionsHook of getSortedPluginHooks('options')) {
if (closed) throwClosedServerError()
options =
(await handleHookPromise(
optionsHook.call(minimalContext, options),
Expand Down Expand Up @@ -675,7 +662,6 @@ export async function createPluginContainer(
let id: string | null = null
const partial: Partial<PartialResolvedId> = {}
for (const plugin of getSortedPlugins('resolveId')) {
if (closed && !ssr) throwClosedServerError()
if (!plugin.resolveId) continue
if (skip?.has(plugin)) continue

Expand Down Expand Up @@ -737,7 +723,6 @@ export async function createPluginContainer(
const ctx = new Context()
ctx.ssr = !!ssr
for (const plugin of getSortedPlugins('load')) {
if (closed && !ssr) throwClosedServerError()
if (!plugin.load) continue
ctx._activePlugin = plugin
const handler = getHookHandler(plugin.load)
Expand All @@ -762,7 +747,6 @@ export async function createPluginContainer(
const ctx = new TransformContext(id, code, inMap as SourceMap)
ctx.ssr = !!ssr
for (const plugin of getSortedPlugins('transform')) {
if (closed && !ssr) throwClosedServerError()
if (!plugin.transform) continue
ctx._activePlugin = plugin
ctx._activeId = id
Expand Down
12 changes: 6 additions & 6 deletions packages/vite/src/node/server/transformRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
injectSourcesContent,
} from './sourcemap'
import { isFileServingAllowed } from './middlewares/static'
import { throwClosedServerError } from './pluginContainer'

export const ERR_LOAD_URL = 'ERR_LOAD_URL'
export const ERR_LOAD_PUBLIC_URL = 'ERR_LOAD_PUBLIC_URL'
Expand All @@ -48,15 +47,17 @@ export interface TransformResult {
export interface TransformOptions {
ssr?: boolean
html?: boolean
/**
* @internal
*/
warmup?: boolean
}

export function transformRequest(
url: string,
server: ViteDevServer,
options: TransformOptions = {},
): Promise<TransformResult | null> {
if (server._restartPromise && !options.ssr) throwClosedServerError()

const cacheKey = (options.ssr ? 'ssr:' : options.html ? 'html:' : '') + url

// This module may get invalidated while we are processing it. For example
Expand Down Expand Up @@ -315,7 +316,7 @@ async function loadAndTransform(
throw err
}

if (server._restartPromise && !ssr) throwClosedServerError()
if (options.warmup && server._restartPromise) return null

// ensure module in graph after successful load
mod ??= await moduleGraph._ensureEntryFromUrl(url, ssr, undefined, resolved)
Expand Down Expand Up @@ -386,8 +387,7 @@ async function loadAndTransform(
}
}
}

if (server._restartPromise && !ssr) throwClosedServerError()
if (options.warmup && server._restartPromise) return null

const result =
ssr && !server.config.experimental.skipSsrTransform
Expand Down