fix: re-ask a failed acting-user lookup when an editor opens a new session

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YLxwAsiXJ1Au8CBDBmH7iY
This commit is contained in:
Diego Imbert
2026-09-09 07:14:22 +02:00
co-authored by Claude Opus 5
parent f3f70da5cc
commit e17684b471
4 changed files with 17 additions and 10 deletions
+12 -10
View File
@@ -25,18 +25,12 @@ export function useActingUser(workspace: () => string | undefined) {
// A Map, not an object: a workspace may legitimately be named `constructor`, which a plain
// object would answer for out of its prototype.
const looked = new SvelteMap<string, RoleLookup>()
// The workspace last asked about, so one selection asks once — a failed lookup included,
// which `getWorkspaceRole` deliberately does not cache. Pointing back at it re-asks.
let asked: string | undefined
$effect(() => {
const ws = workspace()
if (!ws || ws === navWorkspace.current) {
asked = undefined
return
}
if (ws === asked || looked.get(ws)?.kind === 'resolved') return
asked = ws
if (!ws || ws === navWorkspace.current) return
// Any settled answer stops the asking, a failure included — otherwise recording one
// would re-enter this effect and loop.
if (looked.has(ws)) return
untrack(() => {
// Memoized process-wide, so two components pointed at the same workspace share one
// request rather than each issuing their own.
@@ -60,6 +54,14 @@ export function useActingUser(workspace: () => string | undefined) {
!!ws && (ws === navWorkspace.current ? navUser !== undefined : looked.has(ws)),
get current(): UserExt | undefined {
return userIn(workspace())
},
/** Drop the lookups that came back empty so they are asked again. A long-lived editor
* must call this when it starts a fresh session, or one `whoami` that happened to fail
* pins its workspace to "unknown user" for as long as the component lives. */
forgetFailures(): void {
for (const [ws, lookup] of looked) {
if (lookup.kind === 'lookup_failed') looked.delete(ws)
}
}
}
}
@@ -88,6 +88,7 @@
// would still be standing when the next drawer session ends and would swallow that one's
// anchor clear. Every session starts having to clear its own.
keepAnchorOnClose = false
historyUser.forgetFailures()
resource_type = undefined
path = p
selected = effectiveWorkspace
@@ -101,6 +102,7 @@
nDefaultValues?: Record<string, any>
): Promise<void> {
keepAnchorOnClose = false
historyUser.forgetFailures()
path = undefined
resource_type = resourceType
defaultValues = nDefaultValues
@@ -209,6 +209,7 @@
existedInitially = {}
extraPerms = {}
pathError = ''
acting.forgetFailures()
}
export function initNew(): void {
@@ -182,6 +182,7 @@
showLoading = true
}, 100) // Do not show loading spinner for the first 100ms
drawerLoading = true
acting.forgetFailures()
try {
drawer?.openDrawer()
setPageDrawerAnchor(SCHEDULES_PATH, ePath)
@@ -327,6 +328,7 @@
showLoading = true
}, 100) // Do not show loading spinner for the first 100ms
drawerLoading = true
acting.forgetFailures()
try {
let s: Schedule | undefined
if (schedule_path) {