fix(themes): keep last-known-good custom theme on transient file-lock
This commit is contained in:
@@ -63,7 +63,11 @@ internal static class ThemeJsonLoader
|
||||
|
||||
public static Theme LoadFromFile(string path)
|
||||
{
|
||||
var json = File.ReadAllText(path);
|
||||
// FileShare.Read lets concurrent readers and well-behaved editors share
|
||||
// the handle; atomic-replace editors still raise IOException, caught upstream.
|
||||
using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
using var reader = new StreamReader(stream);
|
||||
var json = reader.ReadToEnd();
|
||||
return LoadFromString(json);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,16 @@ public sealed class ThemeRegistry
|
||||
|
||||
public void Switch(string slug) => _active = Get(slug);
|
||||
|
||||
// 0x80070020 = SHARING_VIOLATION, 0x80070021 = LOCK_VIOLATION. Other
|
||||
// IO failures are permanent and get the theme dropped instead of retried.
|
||||
internal static bool IsRecoverableFileLock(Exception? ex)
|
||||
{
|
||||
if (ex is not IOException io)
|
||||
return false;
|
||||
var code = (uint)io.HResult;
|
||||
return code == 0x80070020u || code == 0x80070021u;
|
||||
}
|
||||
|
||||
// Custom-Themes werden lazy aus dem Verzeichnis geladen, Cache mit
|
||||
// LastWriteTime-Token. Eine geänderte JSON wird beim nächsten Lookup
|
||||
// neu eingelesen.
|
||||
@@ -89,12 +99,16 @@ public sealed class ThemeRegistry
|
||||
theme.RecomputeAbgrCache();
|
||||
_customCache[key] = (theme, stamp);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch (Exception ex) when (IsRecoverableFileLock(ex))
|
||||
{
|
||||
// Editor mid-save: keep the cached snapshot, leave the stamp
|
||||
// alone so the next refresh retries automatically.
|
||||
Plugin.Log.Debug($"Custom theme {Path.GetFileName(path)} is locked, keeping last known good");
|
||||
if (cached.Theme is not null)
|
||||
theme = cached.Theme;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Logging passiert in Plugin.cs durch den Aufrufer; hier still
|
||||
// ignorieren, damit ein einzelnes kaputtes JSON nicht alle
|
||||
// Custom-Themes blockt.
|
||||
_ = ex;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user