Skip to content

Commit 87b997b

Browse files
authored
feat(auth): add deprecation notice to onAuthStateChange with async function (#1580)
If you pass in an async function to `onAuthStateChange` and call a Supabase Client API, it's very likely you'll end up with a deadlock. Example: ```typescript supabase.auth.onAuthStateChange(async () => { await supabase.auth.getClaims() }) ``` This is because: - `onAuthStateChange` runs inside an exclusive lock - If you call another API that tries to acquire the exclusive lock, the initial call will never finish, thereby never releasing the first lock, and no other Auth API can be called (across all tabs) Multiple attempts were made to detect these situations but it's not easy as async functions don't track execution context in all environments properly. This change adds a deprecation notice if the callback is an async function to discourage folks from using it, and hopefully make it a bit faster to realize why suddenly everything is frozen.
1 parent 428a7ff commit 87b997b

File tree

1 file changed

+22
-0
lines changed

1 file changed

+22
-0
lines changed

packages/core/auth-js/src/GoTrueClient.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2078,8 +2078,30 @@ export default class GoTrueClient {
20782078

20792079
/**
20802080
* Receive a notification every time an auth event happens.
2081+
* Safe to use without an async function as callback.
2082+
*
20812083
* @param callback A callback function to be invoked when an auth event happens.
20822084
*/
2085+
onAuthStateChange(callback: (event: AuthChangeEvent, session: Session | null) => void): {
2086+
data: { subscription: Subscription }
2087+
}
2088+
2089+
/**
2090+
* Avoid using an async function inside `onAuthStateChange` as you might end
2091+
* up with a deadlock. The callback function runs inside an exclusive lock,
2092+
* so calling other Supabase Client APIs that also try to acquire the
2093+
* exclusive lock, might cause a deadlock. This behavior is observable across
2094+
* tabs. In the next major library version, this behavior will not be supported.
2095+
*
2096+
* Receive a notification every time an auth event happens.
2097+
*
2098+
* @param callback A callback function to be invoked when an auth event happens.
2099+
* @deprecated Due to the possibility of deadlocks with async functions as callbacks, use the version without an async function.
2100+
*/
2101+
onAuthStateChange(callback: (event: AuthChangeEvent, session: Session | null) => Promise<void>): {
2102+
data: { subscription: Subscription }
2103+
}
2104+
20832105
onAuthStateChange(
20842106
callback: (event: AuthChangeEvent, session: Session | null) => void | Promise<void>
20852107
): {

0 commit comments

Comments
 (0)