Files
ScadaBridge/src/ZB.MOM.WW.ScadaBridge.Transport/Import/BundleUnlockRateLimitedException.cs
T
Joseph Doherty 9cff87fe85 docs(comments): strip internal task/milestone/bundle bookkeeping from code comments
Remove project bookkeeping citations from shipped code comments across the
solution: hyphenated task IDs (WP-14, StoreAndForward-025), milestone/task/
issue refs (M3, Task 4, Audit Log #23, #21), Bundle X task-bundle labels,
and C/D/K/S/T phase labels.

Comment text only — no code logic, string/log literals, or XML-doc structure
changed. Genuine descriptions are preserved (only the citation is stripped),
and technical lookalikes are retained (UTF-8, SHA-256, T00:00:00, M365,
UTC-5, pre-C4/pre-C5 schema versions). Flagged by the new CommentChecker
TaskReferenceInComment / TrackingReferenceInComment checks plus targeted
grep passes; full solution builds clean, append-only guard tests pass.
2026-07-07 11:03:26 -04:00

36 lines
1.5 KiB
C#

namespace ZB.MOM.WW.ScadaBridge.Transport.Import;
/// <summary>
/// Thrown by <see cref="BundleImporter.LoadAsync"/> when the caller
/// has exceeded the configured per-IP-per-hour unlock attempt cap
/// (<see cref="TransportOptions.MaxUnlockAttemptsPerIpPerHour"/>). The 429-equivalent
/// signal: the caller must wait for the trailing-hour window to roll forward before
/// another passphrase attempt is accepted.
/// </summary>
public sealed class BundleUnlockRateLimitedException : Exception
{
/// <summary>
/// Rate-limit key the limiter rejected the attempt against — the caller IP when
/// supplied, or the bundle's content hash as the architectural fallback (the
/// importer has no <c>IHttpContext</c> dependency by design).
/// </summary>
public string ClientKey { get; }
/// <summary>Per-window cap that was reached.</summary>
public int Limit { get; }
/// <summary>
/// Initializes a new <see cref="BundleUnlockRateLimitedException"/>.
/// </summary>
/// <param name="clientKey">The rate-limit key that exceeded its budget.</param>
/// <param name="limit">The configured per-window cap.</param>
public BundleUnlockRateLimitedException(string clientKey, int limit)
: base(
$"Bundle unlock rate limit reached ({limit} attempts per hour). "
+ "Wait for the trailing-hour window to expire before retrying.")
{
ClientKey = clientKey ?? throw new ArgumentNullException(nameof(clientKey));
Limit = limit;
}
}