babalae/better-genshin-impact · error · InvalidOperationException
武器名称 OCR 结果为空。
Error message
武器名称 OCR 结果为空。
What it means
`WeaponNameMatcher.MatchClosest` trims the OCR text and throws `InvalidOperationException` if it is null/empty/whitespace. Matching an empty string against the weapon table is meaningless (every distance equals the name length), so it refuses rather than return a garbage 'nearest'. The public `Match` delegates here after the lazy name table loads.
Source
Thrown at BetterGenshinImpact/GameTask/CharacterDevelopment/WeaponNameMatcher.cs:51
private static readonly Lazy<IReadOnlyList<string>> WeaponNames = new(LoadWeaponNames);
/// <summary>
/// 将 OCR 文本匹配为标准武器名称。名称表延迟加载且在进程内复用。
/// </summary>
public static WeaponNameMatch Match(string ocrText)
{
return MatchClosest(ocrText, WeaponNames.Value);
}
/// <summary>
/// 在给定名称表中选择编辑距离最小的名称,并判断该候选是否足够可信。
/// </summary>
internal static WeaponNameMatch MatchClosest(string ocrText, IReadOnlyList<string> weaponNames)
{
var normalizedText = ocrText.Trim();
if (string.IsNullOrWhiteSpace(normalizedText))
{
throw new InvalidOperationException("武器名称 OCR 结果为空。");
}
if (weaponNames.Count == 0)
{
throw new InvalidDataException("武器名称表中没有可用的武器。");
}
var candidates = weaponNames
.Select(name =>
{
var distance = LevenshteinDistance(normalizedText, name);
var maximumLength = Math.Max(normalizedText.Length, name.Length);
var similarity = 1d - (double)distance / maximumLength;
return new WeaponNameMatch(name, distance, similarity, false);
})
.OrderBy(match => match.Distance)
.ThenBy(match => match.Name, StringComparer.Ordinal)
.Take(2)View on GitHub (pinned to a7cb36712d)
Solutions
- Check `string.IsNullOrWhiteSpace(ocrText)` before calling `Match`, and retry/skip when empty (as `ReadWeaponNameWithRetry` already does).
- Ensure the weapon-name ROI actually contains the weapon name line at the current resolution.
- In tests, pass a non-empty OCR string or assert the throw explicitly.
Example fix
// before
var match = WeaponNameMatcher.Match(ocrText); // throws if ocrText is empty
// after
if (string.IsNullOrWhiteSpace(ocrText)) { /* retry / skip */ return; }
var match = WeaponNameMatcher.Match(ocrText); Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrWhiteSpace(ocrText))
return; // or retry; ReadWeaponNameWithRetry already does this
var match = WeaponNameMatcher.Match(ocrText); Try / catch
try { var m = WeaponNameMatcher.Match(text); }
catch (InvalidOperationException ex) when (ex.Message.Contains("武器名称 OCR 结果为空"))
{ /* ROI captured blank; retry or realign weapon-name ROI */ } Prevention
- Guard string.IsNullOrWhiteSpace before calling Match.
- Ensure the weapon-name ROI contains the weapon name line at the current resolution.
- Let ReadWeaponNameWithRetry own the empty-handling; don't bypass it.
When it happens
Trigger: Calling `Match(null)`, `Match("")`, or `Match(" ")`; upstream OCR returning empty for the weapon-name region and that empty value reaching the matcher without a null/empty guard.
Common situations: The weapon-name ROI captured a blank region (misaligned, not yet rendered); a test calls `Match` with empty input; `ReadWeaponNameWithRetry`'s empty-text branch is bypassed by a direct call.
Related errors
- 武器名称 OCR 在 {MaxOcrAttempts} 次内未达到连续 {RequiredStableOcrCount}
- 候选文本不能包含空字符串或纯空白字符串
- 图像通道数必须为3,当前为{channels}
- 不支持的 OCR 引擎类型
- 不支持的 Paddle OCR 模型配置
AI-assisted analysis of babalae/better-genshin-impact@a7cb36712d (2026-08-13).
Data as JSON: /api/errors/5e8b458efd990514.
Report an issue: GitHub.