When a Nanodash instance starts with an empty API cache and no query service that passes the nanopub library's health check, it cannot serve any page at all — not even its error page. Every request ends in a 500.
The failure is in session construction, before any page has a chance to render:
Caused by: java.lang.RuntimeException: Query failed: RAjHh6P11QFUaoPiMRBavdAnTq4YMJW4PB85oVFSBfYjU/get-all-user-intros?
at com.knowledgepixels.nanodash.ApiCache.retrieveResponseSync(ApiCache.java:328)
at com.knowledgepixels.nanodash.domain.UserData.<init>(UserData.java:126)
at com.knowledgepixels.nanodash.domain.User.ensureLoaded(User.java:51)
at com.knowledgepixels.nanodash.domain.User.getUserData(User.java:63)
at com.knowledgepixels.nanodash.domain.User.getIntroNanopubs(User.java:177)
at com.knowledgepixels.nanodash.NanodashSession.loadProfileInfo(NanodashSession.java:146)
at com.knowledgepixels.nanodash.NanodashSession.<init>(NanodashSession.java:79)
at com.knowledgepixels.nanodash.WicketApplication.newSession(WicketApplication.java:345)
at com.knowledgepixels.nanodash.page.NanodashPage.<init>(NanodashPage.java:64)
at com.knowledgepixels.nanodash.page.HomePage.<init>(HomePage.java:59)
NanodashSession's constructor calls loadProfileInfo(), which needs the user list, which ApiCache.retrieveResponseSync refuses to produce after three failed attempts. Wicket then tries to render ErrorPage, which is a NanodashPage and so needs a session of its own; that construction fails the same way, and the request ends as an unhandled NullPointerException:
ERROR WicketApplication - Unhandled exception during request [error/500]
org.apache.wicket.WicketRuntimeException: Can't instantiate page using constructor
'public com.knowledgepixels.nanodash.page.ErrorPage(PageParameters)' ... Caused by: java.lang.NullPointerException
Why it is rarely seen, and when it bites
A warm persistent cache hides it: with get-all-user-intros in the snapshot, session construction succeeds and the instance comes up with stale content while the query service is unavailable. The failure needs both conditions at once — cold cache and no admitted query instance — which is exactly the state of
- a fresh deployment whose query service is still doing its initial load (
Nanopub-Query-Status: LOADING_INITIAL is not admitted by QueryCall.isReadyStatus), and
- any instance started during a query-service outage on a machine without a cache snapshot, e.g. a fresh container.
Observed while testing #671 against a local stack: pointing an instance with an empty cache at a query service that was still loading made every page 500, in a loop, with no way in.
This also defeats the note added for #681: nothing can tell the user that the service is unavailable when no page renders at all.
Suggested behaviour
Session construction should not depend on a query call succeeding. loadProfileInfo wanting the user list is reasonable; treating its absence as fatal is not — an anonymous session with no profile information is a perfectly serviceable state, and the interface can then render, show the #681 note, and recover on its own once the service answers.
Whatever the fix, ErrorPage should be able to render without a working session, or a failure anywhere near session construction will keep turning into an unhandled exception rather than a message.
When a Nanodash instance starts with an empty API cache and no query service that passes the nanopub library's health check, it cannot serve any page at all — not even its error page. Every request ends in a 500.
The failure is in session construction, before any page has a chance to render:
NanodashSession's constructor callsloadProfileInfo(), which needs the user list, whichApiCache.retrieveResponseSyncrefuses to produce after three failed attempts. Wicket then tries to renderErrorPage, which is aNanodashPageand so needs a session of its own; that construction fails the same way, and the request ends as an unhandledNullPointerException:Why it is rarely seen, and when it bites
A warm persistent cache hides it: with
get-all-user-introsin the snapshot, session construction succeeds and the instance comes up with stale content while the query service is unavailable. The failure needs both conditions at once — cold cache and no admitted query instance — which is exactly the state ofNanopub-Query-Status: LOADING_INITIALis not admitted byQueryCall.isReadyStatus), andObserved while testing #671 against a local stack: pointing an instance with an empty cache at a query service that was still loading made every page 500, in a loop, with no way in.
This also defeats the note added for #681: nothing can tell the user that the service is unavailable when no page renders at all.
Suggested behaviour
Session construction should not depend on a query call succeeding.
loadProfileInfowanting the user list is reasonable; treating its absence as fatal is not — an anonymous session with no profile information is a perfectly serviceable state, and the interface can then render, show the #681 note, and recover on its own once the service answers.Whatever the fix,
ErrorPageshould be able to render without a working session, or a failure anywhere near session construction will keep turning into an unhandled exception rather than a message.