| … | … | @@ -50,6 +50,16 @@ const DEFAULT_INTERVAL = 6 * 60 * 60 * 1000 // 6h — a phone is not a server; d |
| 50 | 50 | const COLD_SETTLE_MS = 30000 |
| 51 | 51 | const BUNDLE_NAME = 'worklet.bundle' |
| 52 | 52 | |
| 53 | // ⛔ THE STACK, NOT JUST THE MESSAGE. Three separate homedir defaults have now produced the SAME |
| 54 | // ENOENT on a handset, each masked by the one before it, and each cost a build-and-sideload cycle to |
| 55 | // guess at. `err.message` names the path and not the caller, so it cannot distinguish them. A device |
| 56 | // with no log anyone can read has to carry the frame itself. |
| 57 | const frame = (err) => { |
| 58 | const st = (err && err.stack) || '' |
| 59 | const lines = String(st).split('\n').slice(1, 4).map((l) => l.trim().replace(/^at\s+/, '')) |
| 60 | return lines.length ? ' @ ' + lines.join(' < ') : '' |
| 61 | } |
| 62 | |
| 53 | 63 | const hashOf = (bytes) => crypto.data(Buffer.from(bytes)).toString('hex') |
| 54 | 64 | |
| 55 | 65 | // The running bundle's hash, if the environment happens to say. Guarded because `process` is a shim in |
| … | … | @@ -438,7 +448,7 @@ export async function startOta ({ storage, say = () => {}, repo = DEFAULT_REPO, |
| 438 | 448 | registryKeyHex, repo, destDir: path.join(dir, '.fetch'), swarm, latest: entry |
| 439 | 449 | })) |
| 440 | 450 | } catch (err) { |
| 441 | | say('ota: no swarm fetcher (' + ((err && err.message) || err) + ')') |
| 451 | say('ota: no swarm fetcher (' + ((err && err.message) || err) + ')' + frame(err)) |
| 442 | 452 | return |
| 443 | 453 | } |
| 444 | 454 | } |
| … | … | @@ -454,7 +464,7 @@ export async function startOta ({ storage, say = () => {}, repo = DEFAULT_REPO, |
| 454 | 464 | }) |
| 455 | 465 | runtime.on('updating', (r) => { store.noteRelease(r); say('ota: downloading ' + (r && r.version)) }) |
| 456 | 466 | runtime.on('updated', (i) => say('ota: staged ' + i.newTreeHash + ' — active on next start')) |
| 457 | | runtime.on('error', (e) => say('ota: ' + ((e && e.message) || e))) |
| 467 | runtime.on('error', (e) => say('ota: ' + ((e && e.message) || e) + frame(e))) |
| 458 | 468 | started = runtime.start() |
| 459 | 469 | await started |
| 460 | 470 | } |
| … | … | @@ -473,7 +483,7 @@ export async function startOta ({ storage, say = () => {}, repo = DEFAULT_REPO, |
| 473 | 483 | }) |
| 474 | 484 | say('ota: watching ' + repo + ' — releases arrive as events, not on a timer') |
| 475 | 485 | } catch (err) { |
| 476 | | say('ota: cannot watch the registry (' + ((err && err.message) || err) + ')') |
| 486 | say('ota: cannot watch the registry (' + ((err && err.message) || err) + ')' + frame(err)) |
| 477 | 487 | return null |
| 478 | 488 | } |
| 479 | 489 | } |