Skip to content

Commit 6d2d0e2

Browse files
authoredDec 15, 2023
fix(error pages): account for trailingSlash (#9126)
* account for trailingSlash * add changeset * add tests * update lock file
1 parent c01580a commit 6d2d0e2

28 files changed

+87
-166
lines changed
 

‎.changeset/old-pandas-travel.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'astro': patch
3+
---
4+
5+
Fixes an issue where error pages were not shown when trailingSlash was set to "always".

‎packages/astro/src/core/app/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,8 @@ export class App {
333333
request: Request,
334334
{ status, response: originalResponse, skipMiddleware = false }: RenderErrorOptions
335335
): Promise<Response> {
336-
const errorRouteData = matchRoute('/' + status, this.#manifestData);
336+
const errorRoutePath = `/${status}${this.#manifest.trailingSlash === "always" ? '/' : ''}`;
337+
const errorRouteData = matchRoute(errorRoutePath, this.#manifestData);
337338
const url = new URL(request.url);
338339
if (errorRouteData) {
339340
if (errorRouteData.prerender) {

‎packages/astro/test/custom-404-server.test.js

-45
This file was deleted.

‎packages/astro/test/custom-404.test.js ‎packages/astro/test/custom-404-static.test.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ describe('Custom 404', () => {
77

88
before(async () => {
99
fixture = await loadFixture({
10-
root: './fixtures/custom-404/',
10+
root: './fixtures/custom-404-static/',
1111
site: 'http://example.com',
1212
});
1313
});
@@ -42,4 +42,15 @@ describe('Custom 404', () => {
4242
expect($('p').text()).to.equal('/a');
4343
});
4444
});
45+
46+
describe('build', () => {
47+
before(async () => {
48+
await fixture.build();
49+
})
50+
51+
it('builds to 404.html', async () => {
52+
const html = await fixture.readFile('/404.html');
53+
expect(html).to.be.ok;
54+
});
55+
});
4556
});

‎packages/astro/test/fixtures/custom-404-server/astro.config.mjs

-8
This file was deleted.

‎packages/astro/test/fixtures/custom-404-server/package.json

-8
This file was deleted.

‎packages/astro/test/fixtures/custom-404-server/src/pages/[slug].astro

-6
This file was deleted.

‎packages/astro/test/fixtures/custom-404/src/pages/404.astro

-13
This file was deleted.

‎packages/astro/test/fixtures/custom-404/src/pages/index.astro

-11
This file was deleted.

‎packages/astro/test/fixtures/status-code/package.json

-8
This file was deleted.

‎packages/astro/test/fixtures/status-code/src/pages/404.astro

-8
This file was deleted.

‎packages/astro/test/fixtures/status-code/src/pages/index.astro

-8
This file was deleted.

‎packages/astro/test/ssr-404-500-pages.test.js ‎packages/astro/test/ssr-error-pages.test.js

+61-11
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@ import testAdapter from './test-adapter.js';
44
import * as cheerio from 'cheerio';
55

66
describe('404 and 500 pages', () => {
7-
/** @type {import('./test-utils').Fixture} */
7+
/** @type {import('./test-utils.js').Fixture} */
88
let fixture;
99

1010
before(async () => {
1111
fixture = await loadFixture({
12-
root: './fixtures/ssr-api-route-custom-404/',
12+
root: './fixtures/ssr-error-pages/',
1313
output: 'server',
1414
adapter: testAdapter(),
1515
// test suite was authored when inlineStylesheets defaulted to never
@@ -18,8 +18,9 @@ describe('404 and 500 pages', () => {
1818
});
1919

2020
describe('Development', () => {
21-
/** @type {import('./test-utils').DevServer} */
21+
/** @type {import('./test-utils.js').DevServer} */
2222
let devServer;
23+
2324
before(async () => {
2425
devServer = await fixture.startDevServer();
2526
});
@@ -39,12 +40,15 @@ describe('404 and 500 pages', () => {
3940
});
4041

4142
describe('Production', () => {
43+
/** @type {import('./test-utils.js').App} */
44+
let app;
45+
4246
before(async () => {
4347
await fixture.build({});
48+
app = await fixture.loadTestAdapterApp();
4449
});
4550

4651
it('404 page returned when a route does not match', async () => {
47-
const app = await fixture.loadTestAdapterApp();
4852
const request = new Request('http://example.com/some/fake/route');
4953
const response = await app.render(request);
5054
expect(response.status).to.equal(404);
@@ -54,29 +58,26 @@ describe('404 and 500 pages', () => {
5458
});
5559

5660
it('404 page returned when a route does not match and passing routeData', async () => {
57-
const app = await fixture.loadTestAdapterApp();
5861
const request = new Request('http://example.com/some/fake/route');
5962
const routeData = app.match(request);
60-
const response = await app.render(request, routeData);
63+
const response = await app.render(request, { routeData });
6164
expect(response.status).to.equal(404);
6265
const html = await response.text();
6366
const $ = cheerio.load(html);
6467
expect($('h1').text()).to.equal('Something went horribly wrong!');
6568
});
6669

6770
it('404 page returned when a route does not match and imports are included', async () => {
68-
const app = await fixture.loadTestAdapterApp();
6971
const request = new Request('http://example.com/blog/fake/route');
7072
const routeData = app.match(request);
71-
const response = await app.render(request, routeData);
73+
const response = await app.render(request, { routeData });
7274
expect(response.status).to.equal(404);
7375
const html = await response.text();
7476
const $ = cheerio.load(html);
7577
expect($('head link')).to.have.a.lengthOf(1);
7678
});
7779

7880
it('404 page returned when there is an 404 response returned from route', async () => {
79-
const app = await fixture.loadTestAdapterApp();
8081
const request = new Request('http://example.com/causes-404');
8182
const response = await app.render(request);
8283
expect(response.status).to.equal(404);
@@ -86,7 +87,6 @@ describe('404 and 500 pages', () => {
8687
});
8788

8889
it('500 page returned when there is an error', async () => {
89-
const app = await fixture.loadTestAdapterApp();
9090
const request = new Request('http://example.com/causes-error');
9191
const response = await app.render(request);
9292
expect(response.status).to.equal(500);
@@ -96,7 +96,6 @@ describe('404 and 500 pages', () => {
9696
});
9797

9898
it('Returns 404 when hitting an API route with the wrong method', async () => {
99-
const app = await fixture.loadTestAdapterApp();
10099
const request = new Request('http://example.com/api/route', {
101100
method: 'PUT',
102101
});
@@ -108,3 +107,54 @@ describe('404 and 500 pages', () => {
108107
});
109108
});
110109
});
110+
111+
describe('trailing slashes for error pages', () => {
112+
/** @type {import('./test-utils.js').Fixture} */
113+
let fixture;
114+
115+
before(async () => {
116+
fixture = await loadFixture({
117+
root: './fixtures/ssr-error-pages/',
118+
output: 'server',
119+
adapter: testAdapter(),
120+
trailingSlash: 'always'
121+
});
122+
});
123+
124+
describe('Development', () => {
125+
/** @type {import('./test-utils.js').DevServer} */
126+
let devServer;
127+
128+
before(async () => {
129+
devServer = await fixture.startDevServer();
130+
});
131+
132+
it('renders 404 page when a route does not match the request', async () => {
133+
const response = await fixture.fetch('/ashbfjkasn');
134+
expect(response).to.deep.include({ status: 404 });
135+
const html = await response.text();
136+
expect(html).to.not.be.empty;
137+
const $ = cheerio.load(html);
138+
expect($('h1').text()).to.equal(`Something went horribly wrong!`);
139+
});
140+
});
141+
142+
describe('Production', () => {
143+
/** @type {import('./test-utils.js').App} */
144+
let app;
145+
146+
before(async () => {
147+
await fixture.build({});
148+
app = await fixture.loadTestAdapterApp();
149+
});
150+
151+
it('renders 404 page when a route does not match the request', async () => {
152+
const response = await app.render(new Request('http://example.com/ajksalscla'));
153+
expect(response).to.deep.include({ status: 404 });
154+
const html = await response.text();
155+
expect(html).to.not.be.empty;
156+
const $ = cheerio.load(html);
157+
expect($('h1').text()).to.equal('Something went horribly wrong!');
158+
})
159+
});
160+
});

‎packages/astro/test/status-page.test.js

-19
This file was deleted.

‎pnpm-lock.yaml

+7-19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)
Please sign in to comment.