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

Turbopack: Fix 500 handling in edge with pages router #76155

Merged
merged 1 commit into from
Feb 20, 2025
Merged
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
3 changes: 2 additions & 1 deletion crates/next-api/src/pages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ impl PagesProject {
app: _,
document: _,
error: _,
error_500: _,
} = &*pages_structure.await?;
let mut routes = FxIndexMap::default();

Expand Down Expand Up @@ -711,7 +712,7 @@ impl PageEndpoint {

#[turbo_tasks::function]
fn source(&self) -> Vc<Box<dyn Source>> {
Vc::upcast(FileSource::new(self.page.project_path()))
Vc::upcast(FileSource::new(self.page.file_path()))
}

#[turbo_tasks::function]
Expand Down
30 changes: 22 additions & 8 deletions crates/next-core/src/next_pages/page_entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,13 @@ pub async fn create_page_ssr_entry_module(
INNER.into() => ssr_module,
};

let pages_structure_ref = pages_structure.await?;

if reference_type == ReferenceType::Entry(EntryReferenceSubType::Page) {
inner_assets.insert(
INNER_DOCUMENT.into(),
process_global_item(
pages_structure.document(),
*pages_structure_ref.document,
Value::new(reference_type.clone()),
ssr_module_context,
)
Expand All @@ -130,7 +132,7 @@ pub async fn create_page_ssr_entry_module(
inner_assets.insert(
INNER_APP.into(),
process_global_item(
pages_structure.app(),
*pages_structure_ref.app,
Value::new(reference_type.clone()),
ssr_module_context,
)
Expand Down Expand Up @@ -177,7 +179,7 @@ fn process_global_item(
reference_type: Value<ReferenceType>,
module_context: Vc<Box<dyn AssetContext>>,
) -> Vc<Box<dyn Module>> {
let source = Vc::upcast(FileSource::new(item.project_path()));
let source = Vc::upcast(FileSource::new(item.file_path()));
module_context.process(source, reference_type).module()
}

Expand All @@ -197,6 +199,7 @@ async fn wrap_edge_page(
const INNER_DOCUMENT: &str = "INNER_DOCUMENT";
const INNER_APP: &str = "INNER_APP";
const INNER_ERROR: &str = "INNER_ERROR";
const INNER_ERROR_500: &str = "INNER_500";

let next_config_val = &*next_config.await?;

Expand Down Expand Up @@ -235,30 +238,41 @@ async fn wrap_edge_page(
fxindexmap! {
// TODO
"incrementalCacheHandler" => None,
"userland500Page" => None,
"userland500Page" => pages_structure.await?.error_500.map(|_| INNER_ERROR_500.into()),
},
)
.await?;

let inner_assets = fxindexmap! {
let pages_structure_ref = pages_structure.await?;

let mut inner_assets = fxindexmap! {
INNER.into() => entry,
INNER_DOCUMENT.into() => process_global_item(
pages_structure.document(),
*pages_structure_ref.document,
reference_type.clone(),
asset_context,
).to_resolved().await?,
INNER_APP.into() => process_global_item(
pages_structure.app(),
*pages_structure_ref.app,
reference_type.clone(),
asset_context,
).to_resolved().await?,
INNER_ERROR.into() => process_global_item(
pages_structure.error(),
*pages_structure_ref.error,
reference_type.clone(),
asset_context,
).to_resolved().await?,
};

if let Some(error_500) = pages_structure_ref.error_500 {
inner_assets.insert(
INNER_ERROR_500.into(),
process_global_item(*error_500, reference_type.clone(), asset_context)
.to_resolved()
.await?,
);
}

let wrapped = asset_context
.process(
Vc::upcast(source),
Expand Down
53 changes: 30 additions & 23 deletions crates/next-core/src/pages_structure.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::Result;
use tracing::Instrument;
use turbo_rcstr::RcStr;
use turbo_tasks::{ResolvedVc, TryJoinIterExt, ValueToString, Vc};
use turbo_tasks::{OptionVcExt, ResolvedVc, TryJoinIterExt, ValueToString, Vc};
use turbo_tasks_fs::{
DirectoryContent, DirectoryEntry, FileSystemEntryType, FileSystemPath, FileSystemPathOption,
};
Expand Down Expand Up @@ -45,17 +45,22 @@ impl PagesStructureItem {
}

#[turbo_tasks::function]
pub async fn project_path(&self) -> Result<Vc<FileSystemPath>> {
pub async fn file_path(&self) -> Result<Vc<FileSystemPath>> {
// Check if the file path + extension exists in the filesystem, if so use that. If not fall
// back to the base path.
for ext in self.extensions.await?.into_iter() {
let project_path = self.base_path.append(format!(".{ext}").into());
let ty = *project_path.get_type().await?;
let file_path: Vc<FileSystemPath> = self.base_path.append(format!(".{ext}").into());
let ty = *file_path.get_type().await?;
if matches!(ty, FileSystemEntryType::File | FileSystemEntryType::Symlink) {
return Ok(project_path);
return Ok(file_path);
}
}
if let Some(fallback_path) = self.fallback_path {
Ok(*fallback_path)
} else {
// If the file path that was passed in already has an extension, for example
// `pages/index.js` it won't match the extensions list above because it already had an
// extension and for example `.js.js` obviously won't match
Ok(*self.base_path)
}
}
Expand All @@ -68,28 +73,11 @@ pub struct PagesStructure {
pub app: ResolvedVc<PagesStructureItem>,
pub document: ResolvedVc<PagesStructureItem>,
pub error: ResolvedVc<PagesStructureItem>,
pub error_500: Option<ResolvedVc<PagesStructureItem>>,
pub api: Option<ResolvedVc<PagesDirectoryStructure>>,
pub pages: Option<ResolvedVc<PagesDirectoryStructure>>,
}

#[turbo_tasks::value_impl]
impl PagesStructure {
#[turbo_tasks::function]
pub fn app(&self) -> Vc<PagesStructureItem> {
*self.app
}

#[turbo_tasks::function]
pub fn document(&self) -> Vc<PagesStructureItem> {
*self.document
}

#[turbo_tasks::function]
pub fn error(&self) -> Vc<PagesStructureItem> {
*self.error
}
}

#[turbo_tasks::value]
pub struct PagesDirectoryStructure {
pub project_path: ResolvedVc<FileSystemPath>,
Expand Down Expand Up @@ -157,6 +145,7 @@ async fn get_pages_structure_for_root_directory(
let page_extensions_raw = &*page_extensions.await?;

let mut api_directory = None;
let mut error_500_item = None;

let project_path = project_path.await?;
let pages_directory = if let Some(project_path) = &*project_path {
Expand All @@ -179,6 +168,23 @@ async fn get_pages_structure_for_root_directory(
let base_path = project_path.join(basename.into());
match basename {
"_app" | "_document" | "_error" => {}
"500" => {
let item_next_router_path =
next_router_path_for_basename(next_router_path, basename);
let item_original_path = next_router_path.join(basename.into());
let item = PagesStructureItem::new(
base_path,
page_extensions,
None,
item_next_router_path,
item_original_path,
);

error_500_item = Some(item);

items.push((basename, item));
}

basename => {
let item_next_router_path =
next_router_path_for_basename(next_router_path, basename);
Expand Down Expand Up @@ -294,6 +300,7 @@ async fn get_pages_structure_for_root_directory(
app: app_item.to_resolved().await?,
document: document_item.to_resolved().await?,
error: error_item.to_resolved().await?,
error_500: error_500_item.to_resolved().await?,
api: api_directory,
pages: pages_directory,
}
Expand Down
Loading