From 615a61ee40d9154befd3879675d841845a68f8f8 Mon Sep 17 00:00:00 2001 From: Steffen Deusch Date: Wed, 16 Apr 2025 12:53:07 +0200 Subject: [PATCH 1/2] Catch promise rejections from pushWithReply https://github.com/phoenixframework/phoenix_live_view/pull/3443 changed the pushWithReply function to use promises instead. Previously, if we did not handle the timeout, it was just ignored, but now we reject the promise, which will cause unhandled promise rejections. This PR adds catch clauses to all cases where we previously did not handle the timeout. At the moment, these log an error, but we can also silently drop if we want. cc @chrismccord Supersedes #3760. --- assets/js/phoenix_live_view/view.js | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/assets/js/phoenix_live_view/view.js b/assets/js/phoenix_live_view/view.js index 4e296b8aed..b9b95bad0f 100644 --- a/assets/js/phoenix_live_view/view.js +++ b/assets/js/phoenix_live_view/view.js @@ -1133,7 +1133,9 @@ export default class View { event: event, value: payload, cid: this.closestComponentID(targetCtx) - }).then(({resp: _resp, reply: hookReply}) => onReply(hookReply, ref)) + }) + .then(({resp: _resp, reply: hookReply}) => onReply(hookReply, ref)) + .catch((error) => logError("Failed to push hook event", error)) return ref } @@ -1166,7 +1168,9 @@ export default class View { event: phxEvent, value: this.extractMeta(el, meta, opts.value), cid: this.targetComponentID(el, targetCtx, opts) - }).then(({reply}) => onReply && onReply(reply)) + }) + .then(({reply}) => onReply && onReply(reply)) + .catch((error) => logError("Failed to push event", error)) } pushFileProgress(fileEl, entryRef, progress, onReply = function (){ }){ @@ -1177,7 +1181,9 @@ export default class View { entry_ref: entryRef, progress: progress, cid: view.targetComponentID(fileEl.form, targetCtx) - }).then(({resp}) => onReply(resp)) + }) + .then(({resp}) => onReply(resp)) + .catch((error) => logError("Failed to push file progress", error)) }) } @@ -1242,7 +1248,7 @@ export default class View { } else { callback && callback(resp) } - }) + }).catch((error) => logError("Failed to push input event", error)) } triggerAwaitingSubmit(formEl, phxEvent){ @@ -1341,7 +1347,9 @@ export default class View { value: formData, meta: meta, cid: cid - }).then(({resp}) => onReply(resp)) + }) + .then(({resp}) => onReply(resp)) + .catch((error) => logError("Failed to push form submit", error)) }) } else if(!(formEl.hasAttribute(PHX_REF_SRC) && formEl.classList.contains("phx-submit-loading"))){ let meta = this.extractMeta(formEl, {}, opts.value) @@ -1352,7 +1360,9 @@ export default class View { value: formData, meta: meta, cid: cid - }).then(({resp}) => onReply(resp)) + }) + .then(({resp}) => onReply(resp)) + .catch((error) => logError("Failed to push form submit", error)) } } @@ -1408,7 +1418,7 @@ export default class View { } uploader.initAdapterUpload(resp, onError, this.liveSocket) } - }) + }).catch((error) => logError("Failed to push upload", error)) }) } @@ -1544,10 +1554,10 @@ export default class View { if(completelyDestroyCIDs.length > 0){ this.pushWithReply(null, "cids_destroyed", {cids: completelyDestroyCIDs}).then(({resp}) => { this.rendered.pruneCIDs(resp.cids) - }) + }).catch((error) => logError("Failed to push components destroyed", error)) } }) - }) + }).catch((error) => logError("Failed to push components destroyed", error)) } } From d09ab4e6599eac53e13d3a6a7805e06f2fe6417b Mon Sep 17 00:00:00 2001 From: Steffen Deusch Date: Wed, 16 Apr 2025 18:50:11 +0200 Subject: [PATCH 2/2] don't catch for pushHookEvent --- assets/js/phoenix_live_view/view.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/assets/js/phoenix_live_view/view.js b/assets/js/phoenix_live_view/view.js index b9b95bad0f..33e63a1b8c 100644 --- a/assets/js/phoenix_live_view/view.js +++ b/assets/js/phoenix_live_view/view.js @@ -1133,9 +1133,7 @@ export default class View { event: event, value: payload, cid: this.closestComponentID(targetCtx) - }) - .then(({resp: _resp, reply: hookReply}) => onReply(hookReply, ref)) - .catch((error) => logError("Failed to push hook event", error)) + }).then(({resp: _resp, reply: hookReply}) => onReply(hookReply, ref)) return ref }