dsh-unlag 1.9.15 → 1.9.17

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 +24 -2
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -386,6 +386,12 @@ function pluginReloader(ctx, config) {
386
386
  log(
387
387
  `plugins reloaded (warnings=${warnings.length} pending=${pending.length}${restartReason === null ? '' : ` restart=${restartReason}`})`,
388
388
  )
389
+ /**
390
+ * The count alone cannot say which plugin is not serving now, and that is what a person sees
391
+ * afterwards. The app's own sentence is passed on, cut short so one entry cannot fill the log.
392
+ */
393
+ for (const entry of failedEntries.slice(0, 5)) log(`a plugin did not come back: ${entry.slice(0, 200)}`)
394
+ if (failedEntries.length > 5) log(`and ${failedEntries.length - 5} more did not come back`)
389
395
  return { status: 'done', warnings, pending, restartReason, failedEntries }
390
396
  }
391
397
 
@@ -1133,6 +1139,7 @@ function serveBundlesAtCurrentRevision(ctx) {
1133
1139
  const ask = async (url) => {
1134
1140
  let held = null
1135
1141
  let body
1142
+ let failed = false
1136
1143
  if (url !== originalUrl) {
1137
1144
  try {
1138
1145
  req.url = url
@@ -1161,6 +1168,7 @@ function serveBundlesAtCurrentRevision(ctx) {
1161
1168
  try {
1162
1169
  await Promise.resolve(original(req, res))
1163
1170
  } catch (error) {
1171
+ failed = true
1164
1172
  log(`cannot answer a bundle request: ${error?.message ?? error}`)
1165
1173
  } finally {
1166
1174
  try {
@@ -1170,12 +1178,26 @@ function serveBundlesAtCurrentRevision(ctx) {
1170
1178
  /* the response object owns its own shape */
1171
1179
  }
1172
1180
  }
1173
- return { held, body }
1181
+ return { held, body, failed }
1174
1182
  }
1175
1183
  // The table's own answer first: it still holds the generation this page booted from.
1176
1184
  let outcome = await ask(originalUrl)
1177
1185
  if (outcome.held !== null && retargeted !== null) outcome = await ask(retargeted)
1178
- if (outcome.held === null) return undefined
1186
+ if (outcome.held === null) {
1187
+ /**
1188
+ * The table started writing and then failed. A body that already sent its status cannot take
1189
+ * another one, and a socket left open is a document that waits for a script forever; ending it
1190
+ * lets the page see the failure and carry on.
1191
+ */
1192
+ if (outcome.failed === true) {
1193
+ try {
1194
+ if (res.headersSent === true && res.writableEnded !== true && res.destroyed !== true) realEnd.call(res)
1195
+ } catch {
1196
+ /* the response is gone; nothing left to answer */
1197
+ }
1198
+ }
1199
+ return undefined
1200
+ }
1179
1201
  // The shim resolves the set from the address the page asked for, not the retried one.
1180
1202
  try {
1181
1203
  req.url = originalUrl
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-unlag",
3
- "version": "1.9.15",
3
+ "version": "1.9.17",
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",