Petstore: FailLoud Catalogue
A console page that is misconfigured must fail where the mistake is, with a message that names it. It must not render a half-working page, drop a card, or fall back to a default without telling anyone. The petstore calls this FailLoud. This page explains the rule, shows how the tests exercise it, and lists every case the petstore pins.
What FailLoud means
When a template or a PageSpec is wrong, the render stops with HTTP 500 and the body names the directive, the id and
what to do instead. For example, a badge declared twice, a nav path that does not exist, a body key that is
reserved, or a bytesUrl that points off-site. The message is the contract. The tests assert the text of the
message, not just the status, so a rewording that loses the useful part fails the build.
Two things are worth knowing before you read the table:
- Most cases pin a message, not a code. The reason codes the console used to print (the
E-Bseries for the server-side directives) were replaced by plain messages, so the table lists a code only where an assertion still pins one. A code that appears only in a comment does not count. - Some failures are client-side. The server renders the page successfully and the browser script reports the problem. Those are covered separately, below the main table.
How the tests are built
PetstoreFailLoud_Test renders small fixture templates through three hosts. Each is a minimal REST servlet with the
console FreeMarker mixin:
FixtureHostrendersfailloud/<name>.ftlhinside the productionbase.ftlhchrome, so a fixture is a page in the real petstore frame. It also has two builder routes (/s/badge-duplicateand/s/facts-duplicate) for mistakes that start in aPageSpec, and it registers the petstore's custom card type so the custom-card cases run for real.DevHostis the same chrome with dev mode on. Dev mode validates each page contract against its schema before writing it, so a bad contract is rejected on the server instead of in the browser.ChromeHostuses a small test chrome that includes one fixture. The directives<@navigation>,<@badge>and<@facts>are legal only in a chrome, never in a page, so cases about them need a chrome to put them in.
The fixtures live under src/test/resources/org/apache/juneau/petstore/console/failloud/. Each test renders one,
asserts a 500 and checks that the body contains the expected message.
A manifest, docs-catalogue.txt, lists every FailLoud test with its fixture and any pinned code. A second test,
PetstoreDocsCatalogue_Test, fails the build when a FailLoud test is added without a manifest row, when a catalogued
test or fixture disappears, or (when pointed at a docs checkout) when this page stops mentioning a test id or code.
That is why every test id below appears in the table.
The catalogue
| Test id | Misconfiguration | Fixture | Code / message asserted |
|---|---|---|---|
| a01 | A card with a well-formed but unregistered type | unknown-card-type.ftlh | Message: renders 200 through the generic passthrough ("type":"nope"). The client raises its own error, but no server-side code is asserted |
| a02 | <@page tab> names a path that is not a visible nav node | bad-nav-path.ftlh | Message: <@page tab='pets/nope'> does not match a visible <@node> path; known paths: ... |
| a04 | A card whose JSON5 body does not parse | malformed-json5.ftlh | Message: Card JSON5 is invalid: |
| a05 | <@node under=...> in a page, outside the chrome | node-under-outside-page.ftlh | Message: <@node id='x' under='pets'> must be a direct child of <@page> or <@console>, outside <@navigation>. |
| a06 | <@node under=...> placed inside <@navigation> | node-under-in-navigation.ftlh (ChromeHost, /n/...) | Message: the same must be a direct child of <@page> or <@console>, outside <@navigation>. text, with under='store' |
| a07 | <@node under=...> names a parent that does not exist | node-under-unknown-parent.ftlh | Message: Nav addition under 'nope' does not match a <@node> path in the chrome; known paths: ... |
| a08 | A duplicate sibling <@node> id | none (@Disabled) | Message: <@node id='a'> duplicates a sibling id under '(root)'. The petstore chrome has a fixed nav, so no petstore fixture can duplicate a sibling. The message is asserted in the console FreeMarker bridge tests (ConsoleDirective_Errors_Test in console-ui-freemarker) |
| a10 | A badge id declared in both the PageSpec and the chrome | none (FixtureHost route /s/badge-duplicate) | Message: Badge id 'pending' is declared twice (PageSpec and/or <@badge>). |
| a11 | The viewer roles fact set by both PageSpec.facts and the chrome | none (/s/facts-duplicate) | Message: Fact 'viewer.roles' is set by both PageSpec.facts and the chrome; set it in one place. |
| a12 | A fact with an unsupported value type | facts-bad-type.ftlh (ChromeHost) | Message: Fact 'viewer.roles' has unsupported value type 'Integer'; use string, number, boolean, string list or map. |
| a13 | A visibleWhen rule with an unknown operator | visible-when-bad-op.ftlh (ChromeHost) | Message: <@badge id='b'> visibleWhen op 'nope' is not one of 'eq, ne, present, absent, in, contains'. |
| a14 | A badge scoped to a nav node that is not in the tree | badge-scope-unknown-node.ftlh (ChromeHost) | Message: <@badge id='b'> scope names nav node 'nope', which is not in the nav tree. |
| a15 | An adopter handler that tries to replace a reserved card type | none (ImpostorDatatables, built in the test) | Message, thrown at mixin build time: Card type 'datatables' is reserved and cannot be replaced; reserved: 'chart, datatables, html, job-log, terminal, terminal-view'. |
| a16 | A card body that uses a reserved key | reserved-key.ftlh | Message: <@card id='x'> body key 'title' is reserved; set it as an attribute. |
| a17 | Markup in the body of a datatables card | markup-on-datatables.ftlh | Message: <@card id='x'> type='datatables' requires a JSON5 object body; got '... |
| a18 | A custom card type id that breaks the id pattern | bad-custom-type-id.ftlh | Message: <@card id='x'> type='Gauge_1' must match ^[a-z][a-z0-9-]{0,31}$. |
| a19 | A terminal card whose bytesUrl leaves the origin | terminal-unsafe.ftlh | Message: TerminalDef 'log' bytesUrl must be a same-origin path |
| a20 | The inventory gauge given a species it does not know | gauge-unknown-species.ftlh | Message: <@card id='g'> unknown species 'DRAGON'; choose one of: 'BIRD, CAT, DOG, FISH, MOUSE, RABBIT, SNAKE'. |
| b01 | A pet named </script><script>alert(1)</script> | none (posts through the real REST API) | Escaping: the name never appears raw in the pet page; the text alert(1) appears only escaped |
| b02 | A page whose contract references a template that is not present | dev-bad-template.ftlh (DevHost) | Code R-4: Page contract failed schema validation: 'R-4: template 'missing' is referenced but not present'. Without dev mode the same page renders and the browser reports the problem |
Notes on the table:
- There is no
a03ora09. Neither exists in the current test class. a05anda06are the same rule seen from two places:under=is an addition made from a page or the console root, never from inside the navigation itself.a08is catalogued even though it is disabled, because the rule is real and the table should say where it is covered.
Client-side codes pinned by browser tests
Some mistakes can only be detected in the browser, by the console scripts. The server returns 200 and the script raises a coded error. These codes are pinned by the petstore's browser tests:
| Code | Test | What is asserted |
|---|---|---|
| E-JS-12 | PetstoreCustomCard_BrowserTest | Registering a card type that is already registered (kpi) reports E-JS-12 card type 'kpi' is already registered |
| E-JS-62 | PetstoreDashboard_BrowserTest | A data source or chart fetch that fails reports E-JS-62 with the source or card id |
| E-B4 | ThemesRest_Test | Asserted absent: a nameless <@theme> must not raise a theme error, so the page renders |
Adding a case
- Add a fixture under
failloud/, or a route on one of the hosts if the mistake starts in aPageSpec. - Add a test to
PetstoreFailLoud_Testthat asserts the full message (or a stable prefix, where the message ends in a list that changes with the nav). - Add a row to
docs-catalogue.txtand to the table above.PetstoreDocsCatalogue_Testfails until both exist.
Source: PetstoreFailLoud_Test and the failloud fixtures under
juneau-petstore/juneau-petstore-core/src/test/; the manifest docs-catalogue.txt under the matching test resources;
the framework side in the console-ui-freemarker module's ConsoleDirective_Errors_Test.
Tests: PetstoreFailLoud_Test, PetstoreDocsCatalogue_Test, PetstoreCustomCard_BrowserTest,
PetstoreDashboard_BrowserTest and ThemesRest_Test.
See also
- Petstore: Template and Builder Twins
- Petstore: Custom Cards
- Petstore: Themes
- Building a Console Page: the directives and the page contract.
- Card Asset Dependencies