Skip to content

Commit 37472e6

Browse files
authored
Ensure Promise rejections include stack traces (#3738)
Modify instances where Promise.reject() was called with non-Error values (e.g., strings, plain objects) to consistently use Promise.reject(new Error(...)) instead. The main motivation is debugging where errors are coming from: 1. Stack Traces: Error objects automatically capture a stack trace when created. This trace shows exactly where in the code the rejection originated. Rejecting with strings or other primitives loses this vital information. 2. Consistent Error Handling: Downstream .catch() blocks or async/await try...catch blocks can reliably expect an object with standard error properties (.message, .stack, .name). Handling arbitrary rejected types (strings, numbers, objects) complicates error handling logic and can lead to runtime errors if code tries to access properties that don't exist. 3. Debugging Tools & Libraries: Many debugging tools, error reporting services (like Sentry) are optimized to work with Error objects. Using them ensures better integration and more informative reporting. 4. Predictability & Convention: It's a widely accepted best practice in JavaScript to reject promises with Error objects. Adhering to this convention makes the codebase more predictable and easier for developers to understand and maintain. References: - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject#description - https://forum.sentry.io/t/javascript-unhandledrejection-timeout/6917
1 parent 135598b commit 37472e6

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

assets/js/phoenix_live_view/view.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,7 @@ export default class View {
933933
}
934934

935935
pushWithReply(refGenerator, event, payload){
936-
if(!this.isConnected()){ return Promise.reject({error: "noconnection"}) }
936+
if(!this.isConnected()){ return Promise.reject(new Error("no connection")) }
937937

938938
let [ref, [el], opts] = refGenerator ? refGenerator() : [null, [], {}]
939939
let oldJoinCount = this.joinCount
@@ -970,9 +970,9 @@ export default class View {
970970
finish(null)
971971
}
972972
},
973-
error: (reason) => reject({error: reason}),
973+
error: (reason) => reject(new Error(`failed with reason: ${reason}`)),
974974
timeout: () => {
975-
reject({timeout: true})
975+
reject(new Error("timeout"))
976976
if(this.joinCount === oldJoinCount){
977977
this.liveSocket.reloadWithJitter(this, () => {
978978
this.log("timeout", () => ["received timeout while communicating with server. Falling back to hard refresh for recovery"])

0 commit comments

Comments
 (0)