dsh-unlag 1.9.111 → 1.9.112

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +39 -1
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -2032,7 +2032,7 @@ function serveButton(ctx, controller, config) {
2032
2032
  const disposers = []
2033
2033
  for (const [path, handler] of handlers) {
2034
2034
  try {
2035
- const dispose = server.register({ kind: 'exact', path, handler })
2035
+ const dispose = server.register({ kind: 'exact', path, handler: guardRoute(path, handler) })
2036
2036
  if (typeof dispose === 'function') disposers.push(dispose)
2037
2037
  } catch (error) {
2038
2038
  log(`cannot answer ${path}: ${error?.message ?? error}`)
@@ -2043,6 +2043,44 @@ function serveButton(ctx, controller, config) {
2043
2043
  }
2044
2044
  }
2045
2045
 
2046
+ /**
2047
+ * Nothing a route body does may reach the server as a rejection or a throw: an answer that never
2048
+ * settles is a page that waits forever, and a rejected handler can take down the request instead of
2049
+ * saying what happened. Each body already answers from its own guard; this one is the floor under
2050
+ * them, so a future edit that misses a path still costs a status rather than the answer.
2051
+ */
2052
+ export function guardRoute(path, handler) {
2053
+ /**
2054
+ * Nothing a route body does may reach the server as a rejection or a throw: an answer that never
2055
+ * settles is a page that waits forever, and a rejected handler can take the request down instead
2056
+ * of saying what happened. Each body answers from its own guard already; this is the floor under
2057
+ * them, so a future edit that misses a path costs a status rather than the answer.
2058
+ */
2059
+ return (req, res) => {
2060
+ const fallback = (error) => {
2061
+ log(`cannot answer ${path}: ${error?.message ?? error}`)
2062
+ try {
2063
+ if (res?.headersSent !== true) sendJson(res, 503, { status: 'error' })
2064
+ else if (res?.writableEnded !== true && res?.destroyed !== true) res.end()
2065
+ } catch {
2066
+ /* the response is already gone; the log line is what is left to say */
2067
+ }
2068
+ }
2069
+ try {
2070
+ const answer = handler(req, res)
2071
+ // The answer is handed back as it came: a caller that waits on the body still waits on it,
2072
+ // and the rejection is watched here as well rather than instead.
2073
+ if (answer !== null && typeof answer === 'object' && typeof answer.then === 'function') {
2074
+ answer.then(undefined, fallback)
2075
+ }
2076
+ return answer
2077
+ } catch (error) {
2078
+ fallback(error)
2079
+ return undefined
2080
+ }
2081
+ }
2082
+ }
2083
+
2046
2084
  export function apply(ctx, config) {
2047
2085
  try {
2048
2086
  const instance = {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-unlag",
3
- "version": "1.9.111",
3
+ "version": "1.9.112",
4
4
  "type": "module",
5
5
  "description": "A press applies plugin edits right away and brings a laggy interface back; automatic reloading stays off unless you turn it on, so the press is the only trigger, and nothing restarts.",
6
6
  "license": "MIT",