Improving error messages for invalid client hydration directives (#2076)

* Adding check to make sure the hydration directive is valid

* remove temp debug logging

* Adding a check for media query with client:media + small refactor

* adding changeset

Co-authored-by: Tony Sullivan <tony.sullivan@hyperlab.se>
This commit is contained in:
Tony Sullivan 2021-12-01 22:26:17 +01:00 committed by GitHub
parent bebb312b09
commit 920d3da135
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 64 additions and 0 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Improving build validation and error messages for client hydration directives

View file

@ -31,6 +31,8 @@ export function serializeProps(value: any) {
}); });
} }
const HydrationDirectives = ['load', 'idle', 'media', 'visible', 'only'];
interface ExtractedProps { interface ExtractedProps {
hydration: { hydration: {
directive: string; directive: string;
@ -70,6 +72,17 @@ export function extractDirectives(inputProps: Record<string | number, any>): Ext
default: { default: {
extracted.hydration.directive = key.split(':')[1]; extracted.hydration.directive = key.split(':')[1];
extracted.hydration.value = value; extracted.hydration.value = value;
// throw an error if an invalid hydration directive was provided
if (HydrationDirectives.indexOf(extracted.hydration.directive) < 0) {
throw new Error(`Error: invalid hydration directive "${key}". Supported hydration methods: ${HydrationDirectives.map(d => `"client:${d}"`).join(', ')}`)
}
// throw an error if the query wasn't provided for client:media
if (extracted.hydration.directive === 'media' && typeof extracted.hydration.value !== 'string') {
throw new Error('Error: Media query must be provided for "client:media", similar to client:media="(max-width: 600px)"')
}
break; break;
} }
} }

View file

@ -50,6 +50,36 @@ describe('Error display', () => {
// TODO: improve stacktrace // TODO: improve stacktrace
}); });
it('hydration error', async () => {
if (isMacOS) return;
const res = await fixture.fetch('/astro-hydration-error');
// 500 returned
expect(res.status).to.equal(500);
// error message contains error
const body = await res.text();
// error message contains error
expect(body).to.include('Error: invalid hydration directive');
});
it('client:media error', async () => {
if (isMacOS) return;
const res = await fixture.fetch('/astro-client-media-error');
// 500 returned
expect(res.status).to.equal(500);
// error message contains error
const body = await res.text();
// error message contains error
expect(body).to.include('Error: Media query must be provided');
});
}); });
describe('JS', () => { describe('JS', () => {

View file

@ -0,0 +1,2 @@
<h1>I shouldnt be here</h1>

View file

@ -0,0 +1,7 @@
---
import SvelteDirectiveError from '../components/SvelteDirectiveError.svelte';
---
<div>
<SvelteDirectiveError client:media />
</div>

View file

@ -0,0 +1,7 @@
---
import SvelteDirectiveError from '../components/SvelteDirectiveError.svelte';
---
<div>
<SvelteDirectiveError client:loadm />
</div>