Skip to main content

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-B series 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:

  • FixtureHost renders failloud/<name>.ftlh inside the production base.ftlh chrome, so a fixture is a page in the real petstore frame. It also has two builder routes (/s/badge-duplicate and /s/facts-duplicate) for mistakes that start in a PageSpec, and it registers the petstore's custom card type so the custom-card cases run for real.
  • DevHost is 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.
  • ChromeHost uses 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 idMisconfigurationFixtureCode / message asserted
a01A card with a well-formed but unregistered typeunknown-card-type.ftlhMessage: 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 nodebad-nav-path.ftlhMessage: <@page tab='pets/nope'> does not match a visible <@node> path; known paths: ...
a04A card whose JSON5 body does not parsemalformed-json5.ftlhMessage: Card JSON5 is invalid:
a05<@node under=...> in a page, outside the chromenode-under-outside-page.ftlhMessage: <@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 existnode-under-unknown-parent.ftlhMessage: Nav addition under 'nope' does not match a <@node> path in the chrome; known paths: ...
a08A duplicate sibling <@node> idnone (@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)
a10A badge id declared in both the PageSpec and the chromenone (FixtureHost route /s/badge-duplicate)Message: Badge id 'pending' is declared twice (PageSpec and/or <@badge>).
a11The viewer roles fact set by both PageSpec.facts and the chromenone (/s/facts-duplicate)Message: Fact 'viewer.roles' is set by both PageSpec.facts and the chrome; set it in one place.
a12A fact with an unsupported value typefacts-bad-type.ftlh (ChromeHost)Message: Fact 'viewer.roles' has unsupported value type 'Integer'; use string, number, boolean, string list or map.
a13A visibleWhen rule with an unknown operatorvisible-when-bad-op.ftlh (ChromeHost)Message: <@badge id='b'> visibleWhen op 'nope' is not one of 'eq, ne, present, absent, in, contains'.
a14A badge scoped to a nav node that is not in the treebadge-scope-unknown-node.ftlh (ChromeHost)Message: <@badge id='b'> scope names nav node 'nope', which is not in the nav tree.
a15An adopter handler that tries to replace a reserved card typenone (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'.
a16A card body that uses a reserved keyreserved-key.ftlhMessage: <@card id='x'> body key 'title' is reserved; set it as an attribute.
a17Markup in the body of a datatables cardmarkup-on-datatables.ftlhMessage: <@card id='x'> type='datatables' requires a JSON5 object body; got '...
a18A custom card type id that breaks the id patternbad-custom-type-id.ftlhMessage: <@card id='x'> type='Gauge_1' must match ^[a-z][a-z0-9-]{0,31}$.
a19A terminal card whose bytesUrl leaves the originterminal-unsafe.ftlhMessage: TerminalDef 'log' bytesUrl must be a same-origin path
a20The inventory gauge given a species it does not knowgauge-unknown-species.ftlhMessage: <@card id='g'> unknown species 'DRAGON'; choose one of: 'BIRD, CAT, DOG, FISH, MOUSE, RABBIT, SNAKE'.
b01A 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
b02A page whose contract references a template that is not presentdev-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 a03 or a09. Neither exists in the current test class.
  • a05 and a06 are 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.
  • a08 is 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:

CodeTestWhat is asserted
E-JS-12PetstoreCustomCard_BrowserTestRegistering a card type that is already registered (kpi) reports E-JS-12 card type 'kpi' is already registered
E-JS-62PetstoreDashboard_BrowserTestA data source or chart fetch that fails reports E-JS-62 with the source or card id
E-B4ThemesRest_TestAsserted absent: a nameless <@theme> must not raise a theme error, so the page renders

Adding a case​

  1. Add a fixture under failloud/, or a route on one of the hosts if the mistake starts in a PageSpec.
  2. Add a test to PetstoreFailLoud_Test that asserts the full message (or a stable prefix, where the message ends in a list that changes with the nav).
  3. Add a row to docs-catalogue.txt and to the table above. PetstoreDocsCatalogue_Test fails 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​