From 967773ce9da14be3079bc5d504c29138061abd0c Mon Sep 17 00:00:00 2001 From: David Federman Date: Fri, 6 Mar 2026 22:57:34 -0800 Subject: [PATCH] Use throw helpers --- .github/copilot-instructions.md | 4 +- .github/skills/zwave-implement-cc/SKILL.md | 4 +- src/Shared/BinaryExtensions.cs | 31 ++++++++++++---- .../AssociationCommandClass.Report.cs | 4 +- .../AssociationCommandClass.SpecificGroup.cs | 4 +- ...ociationCommandClass.SupportedGroupings.cs | 4 +- ...roupInformationCommandClass.CommandList.cs | 6 +-- ...nGroupInformationCommandClass.GroupInfo.cs | 8 ++-- ...nGroupInformationCommandClass.GroupName.cs | 6 +-- ...BarrierOperatorCommandClass.EventSignal.cs | 4 +- .../BarrierOperatorCommandClass.Report.cs | 4 +- ...ratorCommandClass.SignalingCapabilities.cs | 4 +- src/ZWave.CommandClasses/BasicCommandClass.cs | 4 +- .../BatteryCommandClass.Health.cs | 8 ++-- .../BatteryCommandClass.Report.cs | 4 +- .../BinarySensorCommandClass.Report.cs | 4 +- ...inarySensorCommandClass.SupportedSensor.cs | 4 +- .../BinarySwitchCommandClass.cs | 4 +- src/ZWave.CommandClasses/ClockCommandClass.cs | 7 ++-- .../ColorSwitchCommandClass.Report.cs | 4 +- .../ColorSwitchCommandClass.Supported.cs | 4 +- src/ZWave.CommandClasses/CommandClass.cs | 8 ++-- .../EntryControlCommandClass.Configuration.cs | 4 +- ...EntryControlCommandClass.EventSupported.cs | 10 ++--- .../EntryControlCommandClass.KeySupported.cs | 6 +-- .../EntryControlCommandClass.Notification.cs | 8 ++-- .../HumidityControlModeCommandClass.Report.cs | 4 +- ...midityControlModeCommandClass.Supported.cs | 4 +- ...midityControlOperatingStateCommandClass.cs | 4 +- ...ontrolSetpointCommandClass.Capabilities.cs | 8 ++-- ...idityControlSetpointCommandClass.Report.cs | 6 +-- ...trolSetpointCommandClass.ScaleSupported.cs | 4 +- ...tyControlSetpointCommandClass.Supported.cs | 4 +- .../ManufacturerSpecificCommandClass.cs | 10 ++--- ...tiChannelAssociationCommandClass.Report.cs | 4 +- ...ociationCommandClass.SupportedGroupings.cs | 4 +- ...tiChannelCommandClass.AggregatedMembers.cs | 4 +- .../MultiChannelCommandClass.Capability.cs | 4 +- ...hannelCommandClass.CommandEncapsulation.cs | 4 +- .../MultiChannelCommandClass.Endpoint.cs | 4 +- .../MultiChannelCommandClass.EndpointFind.cs | 4 +- .../MultilevelSensorCommandClass.Report.cs | 14 +++---- ...ilevelSensorCommandClass.SupportedScale.cs | 10 ++--- ...levelSensorCommandClass.SupportedSensor.cs | 4 +- .../MultilevelSwitchCommandClass.Report.cs | 4 +- .../MultilevelSwitchCommandClass.Supported.cs | 4 +- ...NotificationCommandClass.EventSupported.cs | 6 +-- .../NotificationCommandClass.Report.cs | 4 +- .../NotificationCommandClass.Supported.cs | 6 +-- .../PowerlevelCommandClass.Powerlevel.cs | 4 +- .../PowerlevelCommandClass.TestNode.cs | 6 +-- .../SupervisionCommandClass.Report.cs | 8 ++-- .../TimeCommandClass.Date.cs | 7 ++-- .../TimeCommandClass.Time.cs | 7 ++-- .../TimeCommandClass.TimeOffset.cs | 4 +- .../TimeParametersCommandClass.cs | 7 ++-- .../VersionCommandClass.Capabilities.cs | 4 +- .../VersionCommandClass.CommandClass.cs | 4 +- .../VersionCommandClass.Migration.cs | 8 ++-- .../VersionCommandClass.Report.cs | 6 +-- .../VersionCommandClass.ZWaveSoftware.cs | 4 +- .../WakeUpCommandClass.Interval.cs | 4 +- ...WakeUpCommandClass.IntervalCapabilities.cs | 4 +- .../ZWavePlusInfoCommandClass.cs | 4 +- src/ZWave.Protocol/ZWave.Protocol.csproj | 5 +++ src/ZWave.Protocol/ZWaveException.cs | 37 ++++++++++--------- .../ZWaveSerialPortCoordinator.cs | 17 +++++---- src/ZWave/CommandClassCollection.cs | 11 ++++-- src/ZWave/Controller.cs | 8 ++-- src/ZWave/Driver.cs | 19 +++++----- src/ZWave/Node.cs | 7 +++- 71 files changed, 252 insertions(+), 219 deletions(-) diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 1d1334a..fd530f3 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -58,7 +58,7 @@ Both require `fetch-depth: 0` for Nerdbank.GitVersioning. There is no separate l The foundational layer contains Z-Wave domain types shared across all projects, all in `namespace ZWave;`: - **`CommandClassId`** — Enum of all Z-Wave command class IDs. - **`CommandClassInfo`** — Record struct with CC ID, supported/controlled flags. -- **`ZWaveException`** / **`ZWaveErrorCode`** — Z-Wave-specific error types. +- **`ZWaveException`** / **`ZWaveErrorCode`** — Z-Wave-specific error types. `ZWaveException` has private constructors; use the `[DoesNotReturn]` static `ZWaveException.Throw(errorCode, message)` helpers instead of `throw new ZWaveException(...)`. Use `ArgumentNullException.ThrowIfNull()` and `ArgumentException.ThrowIfNullOrEmpty()` for argument validation. - **`FrequentListeningMode`** / **`NodeType`** — Node classification enums. ### Serial API Layer (`src/ZWave.Serial/`) @@ -116,7 +116,7 @@ Response structs that contain variable-length collections use count + indexer me - **No `var`** — explicit types preferred (`csharp_style_var_*` = `false`). - Allman-style braces (`csharp_new_line_before_open_brace = all`). - NuGet package versions are centrally managed in `Directory.Packages.props`. When adding a package, add the version there and reference it without a version in the `.csproj`. -- `InternalsVisibleTo` is set: `ZWave.Serial` → `ZWave.Serial.Tests`, `ZWave.CommandClasses` → `ZWave` and `ZWave.CommandClasses.Tests`. +- `InternalsVisibleTo` is set: `ZWave.Protocol` → `ZWave.Serial`, `ZWave.Serial` → `ZWave.Serial.Tests`, `ZWave.CommandClasses` → `ZWave` and `ZWave.CommandClasses.Tests`. ## Testing Patterns diff --git a/.github/skills/zwave-implement-cc/SKILL.md b/.github/skills/zwave-implement-cc/SKILL.md index 4c9ab78..20576a9 100644 --- a/.github/skills/zwave-implement-cc/SKILL.md +++ b/.github/skills/zwave-implement-cc/SKILL.md @@ -153,7 +153,7 @@ Validation is performed in the report command's static `Parse` method. The `Pars 1. **Validates** the frame (e.g., minimum payload length, field value ranges) 2. **Logs a warning** via the `ILogger` parameter describing what's wrong -3. **Throws `ZWaveException(ZWaveErrorCode.InvalidPayload, ...)`** with a concise message +3. **Calls `ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, ...)`** with a concise message The base class handles exception propagation differently depending on the report path: @@ -524,7 +524,7 @@ internal readonly struct {Name}ReportCommand : ICommand if (frame.CommandParameters.Length < 1) { logger.LogWarning("{Name} Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "{Name} Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "{Name} Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; diff --git a/src/Shared/BinaryExtensions.cs b/src/Shared/BinaryExtensions.cs index d7d0b14..d6488b4 100644 --- a/src/Shared/BinaryExtensions.cs +++ b/src/Shared/BinaryExtensions.cs @@ -31,15 +31,30 @@ internal static class BinaryExtensions /// Read a signed big-endian integer from a span of 1, 2, or 4 bytes. /// public static int ReadSignedVariableSizeBE(this ReadOnlySpan bytes) - => bytes.Length switch + { + switch (bytes.Length) { - 1 => unchecked((sbyte)bytes[0]), - 2 => BinaryPrimitives.ReadInt16BigEndian(bytes), - 4 => BinaryPrimitives.ReadInt32BigEndian(bytes), - _ => throw new ZWaveException( - ZWaveErrorCode.InvalidPayload, - $"Invalid value size {bytes.Length}. Expected 1, 2, or 4."), - }; + case 1: + { + return unchecked((sbyte)bytes[0]); + } + case 2: + { + return BinaryPrimitives.ReadInt16BigEndian(bytes); + } + case 4: + { + return BinaryPrimitives.ReadInt32BigEndian(bytes); + } + default: + { + ZWaveException.Throw( + ZWaveErrorCode.InvalidPayload, + $"Invalid value size {bytes.Length}. Expected 1, 2, or 4."); + return default; + } + } + } /// /// Get the minimum number of bytes (1, 2, or 4) needed to represent a signed integer. diff --git a/src/ZWave.CommandClasses/AssociationCommandClass.Report.cs b/src/ZWave.CommandClasses/AssociationCommandClass.Report.cs index d30da57..17b923a 100644 --- a/src/ZWave.CommandClasses/AssociationCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/AssociationCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -144,7 +144,7 @@ public static (byte MaxNodesSupported, byte ReportsToFollow) ParseInto( logger.LogWarning( "Association Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Association Report frame is too short"); } diff --git a/src/ZWave.CommandClasses/AssociationCommandClass.SpecificGroup.cs b/src/ZWave.CommandClasses/AssociationCommandClass.SpecificGroup.cs index f940612..64bb112 100644 --- a/src/ZWave.CommandClasses/AssociationCommandClass.SpecificGroup.cs +++ b/src/ZWave.CommandClasses/AssociationCommandClass.SpecificGroup.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -72,7 +72,7 @@ public static byte Parse(CommandClassFrame frame, ILogger logger) logger.LogWarning( "Association Specific Group Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Association Specific Group Report frame is too short"); } diff --git a/src/ZWave.CommandClasses/AssociationCommandClass.SupportedGroupings.cs b/src/ZWave.CommandClasses/AssociationCommandClass.SupportedGroupings.cs index 2cb3099..2723cd6 100644 --- a/src/ZWave.CommandClasses/AssociationCommandClass.SupportedGroupings.cs +++ b/src/ZWave.CommandClasses/AssociationCommandClass.SupportedGroupings.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -69,7 +69,7 @@ public static byte Parse(CommandClassFrame frame, ILogger logger) logger.LogWarning( "Association Supported Groupings Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Association Supported Groupings Report frame is too short"); } diff --git a/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.CommandList.cs b/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.CommandList.cs index c0fa821..a470862 100644 --- a/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.CommandList.cs +++ b/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.CommandList.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -139,7 +139,7 @@ public static (byte GroupingIdentifier, IReadOnlyList C logger.LogWarning( "Association Group Command List Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Association Group Command List Report frame is too short"); } @@ -154,7 +154,7 @@ public static (byte GroupingIdentifier, IReadOnlyList C "Association Group Command List Report frame is too short for declared list length ({DeclaredLength} bytes, but only {Available} available)", listLength, frame.CommandParameters.Length - 2); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Association Group Command List Report frame is too short for declared list length"); } diff --git a/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.GroupInfo.cs b/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.GroupInfo.cs index a5eec46..3111ccc 100644 --- a/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.GroupInfo.cs +++ b/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.GroupInfo.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -162,7 +162,7 @@ public async Task GetGroupInfoAsync(byte groupingIdentifie Logger.LogWarning( "Association Group Info Report for group {GroupId} contained no group entries", groupingIdentifier); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Association Group Info Report contained no group entries"); } @@ -263,7 +263,7 @@ public static (bool DynamicInfo, List Groups) Parse(Comman logger.LogWarning( "Association Group Info Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Association Group Info Report frame is too short"); } @@ -286,7 +286,7 @@ public static (bool DynamicInfo, List Groups) Parse(Comman groupCount, requiredLength, frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Association Group Info Report frame is too short for declared group count"); } diff --git a/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.GroupName.cs b/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.GroupName.cs index 5ead43d..07a1ade 100644 --- a/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.GroupName.cs +++ b/src/ZWave.CommandClasses/AssociationGroupInformationCommandClass.GroupName.cs @@ -1,4 +1,4 @@ -using System.Text; +using System.Text; using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -88,7 +88,7 @@ public static (byte GroupingIdentifier, string Name) Parse(CommandClassFrame fra logger.LogWarning( "Association Group Name Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Association Group Name Report frame is too short"); } @@ -103,7 +103,7 @@ public static (byte GroupingIdentifier, string Name) Parse(CommandClassFrame fra "Association Group Name Report frame is too short for declared name length ({DeclaredLength} bytes, but only {Available} available)", nameLength, frame.CommandParameters.Length - 2); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Association Group Name Report frame is too short for declared name length"); } diff --git a/src/ZWave.CommandClasses/BarrierOperatorCommandClass.EventSignal.cs b/src/ZWave.CommandClasses/BarrierOperatorCommandClass.EventSignal.cs index 330fbcd..551b266 100644 --- a/src/ZWave.CommandClasses/BarrierOperatorCommandClass.EventSignal.cs +++ b/src/ZWave.CommandClasses/BarrierOperatorCommandClass.EventSignal.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -136,7 +136,7 @@ public static BarrierOperatorEventSignalReport Parse(CommandClassFrame frame, IL logger.LogWarning( "Barrier Operator Event Signaling Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Barrier Operator Event Signaling Report frame is too short"); } diff --git a/src/ZWave.CommandClasses/BarrierOperatorCommandClass.Report.cs b/src/ZWave.CommandClasses/BarrierOperatorCommandClass.Report.cs index dcc866d..09508cb 100644 --- a/src/ZWave.CommandClasses/BarrierOperatorCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/BarrierOperatorCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -146,7 +146,7 @@ public static BarrierOperatorReport Parse(CommandClassFrame frame, ILogger logge if (frame.CommandParameters.Length < 1) { logger.LogWarning("Barrier Operator Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Barrier Operator Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Barrier Operator Report frame is too short"); } byte stateValue = frame.CommandParameters.Span[0]; diff --git a/src/ZWave.CommandClasses/BarrierOperatorCommandClass.SignalingCapabilities.cs b/src/ZWave.CommandClasses/BarrierOperatorCommandClass.SignalingCapabilities.cs index cde1a87..b457671 100644 --- a/src/ZWave.CommandClasses/BarrierOperatorCommandClass.SignalingCapabilities.cs +++ b/src/ZWave.CommandClasses/BarrierOperatorCommandClass.SignalingCapabilities.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -68,7 +68,7 @@ public static IReadOnlySet Parse(CommandC logger.LogWarning( "Barrier Operator Signal Supported Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Barrier Operator Signal Supported Report frame is too short"); } diff --git a/src/ZWave.CommandClasses/BasicCommandClass.cs b/src/ZWave.CommandClasses/BasicCommandClass.cs index e36ee33..f1fd7f6 100644 --- a/src/ZWave.CommandClasses/BasicCommandClass.cs +++ b/src/ZWave.CommandClasses/BasicCommandClass.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -171,7 +171,7 @@ public static BasicReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 1) { logger.LogWarning("Basic Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Basic Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Basic Report frame is too short"); } GenericValue currentValue = frame.CommandParameters.Span[0]; diff --git a/src/ZWave.CommandClasses/BatteryCommandClass.Health.cs b/src/ZWave.CommandClasses/BatteryCommandClass.Health.cs index 0df8adc..d401954 100644 --- a/src/ZWave.CommandClasses/BatteryCommandClass.Health.cs +++ b/src/ZWave.CommandClasses/BatteryCommandClass.Health.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -85,7 +85,7 @@ public static BatteryHealth Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 2) { logger.LogWarning("Battery Health Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Battery Health Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Battery Health Report frame is too short"); } // 0xff means unknown. @@ -109,7 +109,7 @@ BatteryTemperatureScale batteryTemperatureScale if (valueSize != 1 && valueSize != 2 && valueSize != 4) { logger.LogWarning("Battery Health Report has invalid Size value ({Size}). Expected 0, 1, 2, or 4", valueSize); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Battery Health Report has invalid Size value"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Battery Health Report has invalid Size value"); } if (frame.CommandParameters.Length < 2 + valueSize) @@ -118,7 +118,7 @@ BatteryTemperatureScale batteryTemperatureScale "Battery Health Report frame value size ({ValueSize}) exceeds remaining bytes ({Remaining})", valueSize, frame.CommandParameters.Length - 2); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Battery Health Report frame is too short for declared value size"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Battery Health Report frame is too short for declared value size"); } ReadOnlySpan valueBytes = frame.CommandParameters.Span.Slice(2, valueSize); diff --git a/src/ZWave.CommandClasses/BatteryCommandClass.Report.cs b/src/ZWave.CommandClasses/BatteryCommandClass.Report.cs index 507685f..ff0ce81 100644 --- a/src/ZWave.CommandClasses/BatteryCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/BatteryCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -115,7 +115,7 @@ public static BatteryReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 1) { logger.LogWarning("Battery Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Battery Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Battery Report frame is too short"); } BatteryLevel batteryLevel = frame.CommandParameters.Span[0]; diff --git a/src/ZWave.CommandClasses/BinarySensorCommandClass.Report.cs b/src/ZWave.CommandClasses/BinarySensorCommandClass.Report.cs index d1add68..36f353b 100644 --- a/src/ZWave.CommandClasses/BinarySensorCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/BinarySensorCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -115,7 +115,7 @@ public static BinarySensorReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 1) { logger.LogWarning("Binary Sensor Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Binary Sensor Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Binary Sensor Report frame is too short"); } bool sensorValue = frame.CommandParameters.Span[0] == 0xff; diff --git a/src/ZWave.CommandClasses/BinarySensorCommandClass.SupportedSensor.cs b/src/ZWave.CommandClasses/BinarySensorCommandClass.SupportedSensor.cs index 576decb..e547591 100644 --- a/src/ZWave.CommandClasses/BinarySensorCommandClass.SupportedSensor.cs +++ b/src/ZWave.CommandClasses/BinarySensorCommandClass.SupportedSensor.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -75,7 +75,7 @@ public static IReadOnlySet Parse(CommandClassFrame frame, ILog if (frame.CommandParameters.Length < 1) { logger.LogWarning("Binary Sensor Supported Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Binary Sensor Supported Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Binary Sensor Supported Report frame is too short"); } return BitMaskHelper.ParseBitMask(frame.CommandParameters.Span); diff --git a/src/ZWave.CommandClasses/BinarySwitchCommandClass.cs b/src/ZWave.CommandClasses/BinarySwitchCommandClass.cs index e6b8d18..ef4eff2 100644 --- a/src/ZWave.CommandClasses/BinarySwitchCommandClass.cs +++ b/src/ZWave.CommandClasses/BinarySwitchCommandClass.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -177,7 +177,7 @@ public static BinarySwitchReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 1) { logger.LogWarning("Binary Switch Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Binary Switch Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Binary Switch Report frame is too short"); } GenericValue currentValue = frame.CommandParameters.Span[0]; diff --git a/src/ZWave.CommandClasses/ClockCommandClass.cs b/src/ZWave.CommandClasses/ClockCommandClass.cs index c2d30d1..d1cff7c 100644 --- a/src/ZWave.CommandClasses/ClockCommandClass.cs +++ b/src/ZWave.CommandClasses/ClockCommandClass.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -225,7 +225,7 @@ public static ClockReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 2) { logger.LogWarning("Clock Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Clock Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Clock Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; @@ -240,7 +240,8 @@ public static ClockReport Parse(CommandClassFrame frame, ILogger logger) catch (ArgumentOutOfRangeException) { logger.LogWarning("Clock Report has invalid time values (hour={Hour}, minute={Minute})", hour, minute); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Clock Report has invalid time values"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Clock Report has invalid time values"); + return default; } } } diff --git a/src/ZWave.CommandClasses/ColorSwitchCommandClass.Report.cs b/src/ZWave.CommandClasses/ColorSwitchCommandClass.Report.cs index b3fd533..7b32902 100644 --- a/src/ZWave.CommandClasses/ColorSwitchCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/ColorSwitchCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -112,7 +112,7 @@ public static ColorSwitchReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 2) { logger.LogWarning("Color Switch Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Color Switch Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Color Switch Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/ColorSwitchCommandClass.Supported.cs b/src/ZWave.CommandClasses/ColorSwitchCommandClass.Supported.cs index bc4895d..91e0a1d 100644 --- a/src/ZWave.CommandClasses/ColorSwitchCommandClass.Supported.cs +++ b/src/ZWave.CommandClasses/ColorSwitchCommandClass.Supported.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -82,7 +82,7 @@ public static IReadOnlySet Parse(CommandClassFrame fr if (frame.CommandParameters.Length < 1) { logger.LogWarning("Color Switch Supported Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Color Switch Supported Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Color Switch Supported Report frame is too short"); } return BitMaskHelper.ParseBitMask(frame.CommandParameters.Span); diff --git a/src/ZWave.CommandClasses/CommandClass.cs b/src/ZWave.CommandClasses/CommandClass.cs index 3ad3e22..12fa8ff 100644 --- a/src/ZWave.CommandClasses/CommandClass.cs +++ b/src/ZWave.CommandClasses/CommandClass.cs @@ -1,3 +1,4 @@ +using System.Diagnostics; using System.Runtime.CompilerServices; using Microsoft.Extensions.Logging; @@ -12,10 +13,7 @@ public abstract class CommandClass : CommandClass internal CommandClass(CommandClassInfo info, IDriver driver, IEndpoint endpoint, ILogger logger) : base(info, driver, endpoint, logger) { - if (Unsafe.SizeOf() != Unsafe.SizeOf()) - { - throw new ArgumentException($"The generic type '{typeof(TCommand).Name}' must be an enum with backing type byte."); - } + Debug.Assert(Unsafe.SizeOf() == sizeof(byte), $"The generic type '{typeof(TCommand).Name}' must be an enum with backing type byte."); } /// @@ -178,7 +176,7 @@ internal async Task SendCommandAsync( { if (!IsCommandSupported(TRequest.CommandId).GetValueOrDefault()) { - throw new ZWaveException(ZWaveErrorCode.CommandNotSupported, "This command is not supported by this node"); + ZWaveException.Throw(ZWaveErrorCode.CommandNotSupported, "This command is not supported by this node"); } await Driver.SendCommandAsync(command, Endpoint.NodeId, Endpoint.EndpointIndex, cancellationToken).ConfigureAwait(false); diff --git a/src/ZWave.CommandClasses/EntryControlCommandClass.Configuration.cs b/src/ZWave.CommandClasses/EntryControlCommandClass.Configuration.cs index 74869be..ffa22b9 100644 --- a/src/ZWave.CommandClasses/EntryControlCommandClass.Configuration.cs +++ b/src/ZWave.CommandClasses/EntryControlCommandClass.Configuration.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -110,7 +110,7 @@ public static EntryControlConfigurationReport Parse(CommandClassFrame frame, ILo logger.LogWarning( "Entry Control Configuration Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Entry Control Configuration Report frame is too short"); } diff --git a/src/ZWave.CommandClasses/EntryControlCommandClass.EventSupported.cs b/src/ZWave.CommandClasses/EntryControlCommandClass.EventSupported.cs index 2da38de..cd07942 100644 --- a/src/ZWave.CommandClasses/EntryControlCommandClass.EventSupported.cs +++ b/src/ZWave.CommandClasses/EntryControlCommandClass.EventSupported.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -97,7 +97,7 @@ public static EntryControlEventSupportedReport Parse(CommandClassFrame frame, IL logger.LogWarning( "Entry Control Event Supported Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Entry Control Event Supported Report frame is too short"); } @@ -115,7 +115,7 @@ public static EntryControlEventSupportedReport Parse(CommandClassFrame frame, IL logger.LogWarning( "Entry Control Event Supported Report too short for data type bitmask ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Entry Control Event Supported Report frame is too short for data type bitmask"); } @@ -131,7 +131,7 @@ public static EntryControlEventSupportedReport Parse(CommandClassFrame frame, IL logger.LogWarning( "Entry Control Event Supported Report too short for event type bitmask length ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Entry Control Event Supported Report frame is too short for event type bitmask length"); } @@ -146,7 +146,7 @@ public static EntryControlEventSupportedReport Parse(CommandClassFrame frame, IL "Entry Control Event Supported Report too short for event bitmask and config ({Length} bytes, need {Expected})", frame.CommandParameters.Length, offset + eventTypeBitmaskLength + 4); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Entry Control Event Supported Report frame is too short for event bitmask and configuration"); } diff --git a/src/ZWave.CommandClasses/EntryControlCommandClass.KeySupported.cs b/src/ZWave.CommandClasses/EntryControlCommandClass.KeySupported.cs index 6937512..802bdf8 100644 --- a/src/ZWave.CommandClasses/EntryControlCommandClass.KeySupported.cs +++ b/src/ZWave.CommandClasses/EntryControlCommandClass.KeySupported.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -63,7 +63,7 @@ public static IReadOnlySet Parse(CommandClassFrame frame, ILogger logger) logger.LogWarning( "Entry Control Key Supported Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Entry Control Key Supported Report frame is too short"); } @@ -77,7 +77,7 @@ public static IReadOnlySet Parse(CommandClassFrame frame, ILogger logger) "Entry Control Key Supported Report frame too short for declared bitmask ({Length} bytes, need {Expected})", frame.CommandParameters.Length, 1 + bitMaskLength); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Entry Control Key Supported Report frame is too short for bitmask"); } diff --git a/src/ZWave.CommandClasses/EntryControlCommandClass.Notification.cs b/src/ZWave.CommandClasses/EntryControlCommandClass.Notification.cs index 189c4a2..a70ce32 100644 --- a/src/ZWave.CommandClasses/EntryControlCommandClass.Notification.cs +++ b/src/ZWave.CommandClasses/EntryControlCommandClass.Notification.cs @@ -1,4 +1,4 @@ -using System.Text; +using System.Text; using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -69,7 +69,7 @@ public static EntryControlNotification Parse(CommandClassFrame frame, ILogger lo logger.LogWarning( "Entry Control Notification frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Entry Control Notification frame is too short"); } @@ -86,7 +86,7 @@ public static EntryControlNotification Parse(CommandClassFrame frame, ILogger lo logger.LogWarning( "Entry Control Notification event data length {Length} exceeds maximum of 32", eventDataLength); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Entry Control Notification event data length exceeds maximum"); } @@ -97,7 +97,7 @@ public static EntryControlNotification Parse(CommandClassFrame frame, ILogger lo "Entry Control Notification frame too short for declared event data ({Length} bytes, need {Expected})", frame.CommandParameters.Length, 4 + eventDataLength); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Entry Control Notification frame is too short for event data"); } diff --git a/src/ZWave.CommandClasses/HumidityControlModeCommandClass.Report.cs b/src/ZWave.CommandClasses/HumidityControlModeCommandClass.Report.cs index 9daf6e3..4d04ca2 100644 --- a/src/ZWave.CommandClasses/HumidityControlModeCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/HumidityControlModeCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -105,7 +105,7 @@ public static HumidityControlModeReport Parse(CommandClassFrame frame, ILogger l if (frame.CommandParameters.Length < 1) { logger.LogWarning("Humidity Control Mode Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Humidity Control Mode Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Humidity Control Mode Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/HumidityControlModeCommandClass.Supported.cs b/src/ZWave.CommandClasses/HumidityControlModeCommandClass.Supported.cs index 8661802..ee859ad 100644 --- a/src/ZWave.CommandClasses/HumidityControlModeCommandClass.Supported.cs +++ b/src/ZWave.CommandClasses/HumidityControlModeCommandClass.Supported.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -60,7 +60,7 @@ public static IReadOnlySet Parse(CommandClassFrame frame, I if (frame.CommandParameters.Length < 1) { logger.LogWarning("Humidity Control Mode Supported Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Humidity Control Mode Supported Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Humidity Control Mode Supported Report frame is too short"); } return BitMaskHelper.ParseBitMask(frame.CommandParameters.Span, startBit: 1); diff --git a/src/ZWave.CommandClasses/HumidityControlOperatingStateCommandClass.cs b/src/ZWave.CommandClasses/HumidityControlOperatingStateCommandClass.cs index e357f78..1aa86fe 100644 --- a/src/ZWave.CommandClasses/HumidityControlOperatingStateCommandClass.cs +++ b/src/ZWave.CommandClasses/HumidityControlOperatingStateCommandClass.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -145,7 +145,7 @@ public static HumidityControlOperatingState Parse(CommandClassFrame frame, ILogg if (frame.CommandParameters.Length < 1) { logger.LogWarning("Humidity Control Operating State Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Humidity Control Operating State Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Humidity Control Operating State Report frame is too short"); } return (HumidityControlOperatingState)(frame.CommandParameters.Span[0] & 0x0F); diff --git a/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Capabilities.cs b/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Capabilities.cs index 5b0e6b9..b4085c1 100644 --- a/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Capabilities.cs +++ b/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Capabilities.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -104,7 +104,7 @@ public static HumidityControlSetpointCapabilities Parse(CommandClassFrame frame, if (frame.CommandParameters.Length < 3) { logger.LogWarning("Humidity Control Setpoint Capabilities Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Capabilities Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Capabilities Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; @@ -119,7 +119,7 @@ public static HumidityControlSetpointCapabilities Parse(CommandClassFrame frame, "Humidity Control Setpoint Capabilities Report frame is too short for minimum value ({Length} bytes, need {Needed})", frame.CommandParameters.Length, 2 + minValueSize + 1); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Capabilities Report frame is too short for minimum value"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Capabilities Report frame is too short for minimum value"); } ReadOnlySpan minValueBytes = span.Slice(2, minValueSize); @@ -135,7 +135,7 @@ public static HumidityControlSetpointCapabilities Parse(CommandClassFrame frame, "Humidity Control Setpoint Capabilities Report frame is too short for maximum value ({Length} bytes, need {Needed})", frame.CommandParameters.Length, maxPssOffset + 1 + maxValueSize); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Capabilities Report frame is too short for maximum value"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Capabilities Report frame is too short for maximum value"); } ReadOnlySpan maxValueBytes = span.Slice(maxPssOffset + 1, maxValueSize); diff --git a/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Report.cs b/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Report.cs index 1ef2a6e..d3cf9c8 100644 --- a/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -139,7 +139,7 @@ public static HumidityControlSetpointReport Parse(CommandClassFrame frame, ILogg if (frame.CommandParameters.Length < 2) { logger.LogWarning("Humidity Control Setpoint Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; @@ -152,7 +152,7 @@ public static HumidityControlSetpointReport Parse(CommandClassFrame frame, ILogg "Humidity Control Setpoint Report frame value size ({ValueSize}) exceeds remaining bytes ({Remaining})", valueSize, frame.CommandParameters.Length - 2); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Report frame is too short for declared value size"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Report frame is too short for declared value size"); } ReadOnlySpan valueBytes = span.Slice(2, valueSize); diff --git a/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.ScaleSupported.cs b/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.ScaleSupported.cs index fa32e02..e7ba3ef 100644 --- a/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.ScaleSupported.cs +++ b/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.ScaleSupported.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -68,7 +68,7 @@ public static IReadOnlySet Parse(CommandClassFrame if (frame.CommandParameters.Length < 1) { logger.LogWarning("Humidity Control Setpoint Scale Supported Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Scale Supported Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Scale Supported Report frame is too short"); } HashSet supportedScales = []; diff --git a/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Supported.cs b/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Supported.cs index f6eb8cd..4405ca9 100644 --- a/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Supported.cs +++ b/src/ZWave.CommandClasses/HumidityControlSetpointCommandClass.Supported.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -76,7 +76,7 @@ public static IReadOnlySet Parse(CommandClassFrame if (frame.CommandParameters.Length < 1) { logger.LogWarning("Humidity Control Setpoint Supported Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Supported Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Humidity Control Setpoint Supported Report frame is too short"); } return BitMaskHelper.ParseBitMask(frame.CommandParameters.Span, startBit: 1); diff --git a/src/ZWave.CommandClasses/ManufacturerSpecificCommandClass.cs b/src/ZWave.CommandClasses/ManufacturerSpecificCommandClass.cs index 5c1c961..adde2b3 100644 --- a/src/ZWave.CommandClasses/ManufacturerSpecificCommandClass.cs +++ b/src/ZWave.CommandClasses/ManufacturerSpecificCommandClass.cs @@ -1,4 +1,4 @@ -using System.Text; +using System.Text; using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -226,7 +226,7 @@ public static ManufacturerInformation Parse(CommandClassFrame frame, ILogger log if (frame.CommandParameters.Length < 6) { logger.LogWarning("Manufacturer Specific Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Manufacturer Specific Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Manufacturer Specific Report frame is too short"); } ushort manufacturerId = frame.CommandParameters.Span[0..2].ToUInt16BE(); @@ -275,7 +275,7 @@ public static DeviceSpecificReport Parse(CommandClassFrame frame, ILogger logger if (frame.CommandParameters.Length < 2) { logger.LogWarning("Device Specific Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Device Specific Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Device Specific Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; @@ -288,7 +288,7 @@ public static DeviceSpecificReport Parse(CommandClassFrame frame, ILogger logger if (deviceIdDataLength == 0) { logger.LogWarning("Device Specific Report has zero Device ID Data Length"); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Device Specific Report has zero Device ID Data Length"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Device Specific Report has zero Device ID Data Length"); } if (frame.CommandParameters.Length < 2 + deviceIdDataLength) @@ -297,7 +297,7 @@ public static DeviceSpecificReport Parse(CommandClassFrame frame, ILogger logger "Device Specific Report frame is too short for declared data length ({Length} bytes, expected at least {Expected})", frame.CommandParameters.Length, 2 + deviceIdDataLength); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Device Specific Report frame is too short for declared data length"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Device Specific Report frame is too short for declared data length"); } ReadOnlySpan deviceIdData = span.Slice(2, deviceIdDataLength); diff --git a/src/ZWave.CommandClasses/MultiChannelAssociationCommandClass.Report.cs b/src/ZWave.CommandClasses/MultiChannelAssociationCommandClass.Report.cs index 0ca4028..a2cd4e8 100644 --- a/src/ZWave.CommandClasses/MultiChannelAssociationCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/MultiChannelAssociationCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -124,7 +124,7 @@ public static (byte MaxNodesSupported, byte ReportsToFollow) ParseInto( logger.LogWarning( "Multi Channel Association Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Multi Channel Association Report frame is too short"); } diff --git a/src/ZWave.CommandClasses/MultiChannelAssociationCommandClass.SupportedGroupings.cs b/src/ZWave.CommandClasses/MultiChannelAssociationCommandClass.SupportedGroupings.cs index 4649e86..9a7b2ed 100644 --- a/src/ZWave.CommandClasses/MultiChannelAssociationCommandClass.SupportedGroupings.cs +++ b/src/ZWave.CommandClasses/MultiChannelAssociationCommandClass.SupportedGroupings.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -62,7 +62,7 @@ public static byte Parse(CommandClassFrame frame, ILogger logger) logger.LogWarning( "Multi Channel Association Supported Groupings Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.InvalidPayload, "Multi Channel Association Supported Groupings Report frame is too short"); } diff --git a/src/ZWave.CommandClasses/MultiChannelCommandClass.AggregatedMembers.cs b/src/ZWave.CommandClasses/MultiChannelCommandClass.AggregatedMembers.cs index 17ad6ae..7a9418a 100644 --- a/src/ZWave.CommandClasses/MultiChannelCommandClass.AggregatedMembers.cs +++ b/src/ZWave.CommandClasses/MultiChannelCommandClass.AggregatedMembers.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -83,7 +83,7 @@ public static IReadOnlyList Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 2) { logger.LogWarning("Multi Channel Aggregated Members Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Multi Channel Aggregated Members Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Multi Channel Aggregated Members Report frame is too short"); } ReadOnlySpan parameters = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/MultiChannelCommandClass.Capability.cs b/src/ZWave.CommandClasses/MultiChannelCommandClass.Capability.cs index cb74399..b505318 100644 --- a/src/ZWave.CommandClasses/MultiChannelCommandClass.Capability.cs +++ b/src/ZWave.CommandClasses/MultiChannelCommandClass.Capability.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -116,7 +116,7 @@ public static MultiChannelCapabilityReport Parse(CommandClassFrame frame, ILogge if (frame.CommandParameters.Length < 3) { logger.LogWarning("Multi Channel Capability Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Multi Channel Capability Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Multi Channel Capability Report frame is too short"); } ReadOnlySpan parameters = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/MultiChannelCommandClass.CommandEncapsulation.cs b/src/ZWave.CommandClasses/MultiChannelCommandClass.CommandEncapsulation.cs index 5af18ea..12c868f 100644 --- a/src/ZWave.CommandClasses/MultiChannelCommandClass.CommandEncapsulation.cs +++ b/src/ZWave.CommandClasses/MultiChannelCommandClass.CommandEncapsulation.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -131,7 +131,7 @@ public static MultiChannelCommandEncapsulation Parse(CommandClassFrame frame, IL if (frame.CommandParameters.Length < 4) { logger.LogWarning("Multi Channel Command Encapsulation frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Multi Channel Command Encapsulation frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Multi Channel Command Encapsulation frame is too short"); } ReadOnlySpan parameters = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/MultiChannelCommandClass.Endpoint.cs b/src/ZWave.CommandClasses/MultiChannelCommandClass.Endpoint.cs index 51923ba..fed31fc 100644 --- a/src/ZWave.CommandClasses/MultiChannelCommandClass.Endpoint.cs +++ b/src/ZWave.CommandClasses/MultiChannelCommandClass.Endpoint.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -99,7 +99,7 @@ public static MultiChannelEndpointReport Parse(CommandClassFrame frame, ILogger if (frame.CommandParameters.Length < 2) { logger.LogWarning("Multi Channel End Point Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Multi Channel End Point Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Multi Channel End Point Report frame is too short"); } ReadOnlySpan parameters = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/MultiChannelCommandClass.EndpointFind.cs b/src/ZWave.CommandClasses/MultiChannelCommandClass.EndpointFind.cs index 277e835..4d8f9f1 100644 --- a/src/ZWave.CommandClasses/MultiChannelCommandClass.EndpointFind.cs +++ b/src/ZWave.CommandClasses/MultiChannelCommandClass.EndpointFind.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -103,7 +103,7 @@ public static byte Parse( if (frame.CommandParameters.Length < 3) { logger.LogWarning("Multi Channel End Point Find Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Multi Channel End Point Find Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Multi Channel End Point Find Report frame is too short"); } ReadOnlySpan parameters = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/MultilevelSensorCommandClass.Report.cs b/src/ZWave.CommandClasses/MultilevelSensorCommandClass.Report.cs index 8cf2d4b..145f6c9 100644 --- a/src/ZWave.CommandClasses/MultilevelSensorCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/MultilevelSensorCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -59,24 +59,24 @@ public async Task GetAsync( { if (SupportedSensorTypes == null) { - throw new ZWaveException(ZWaveErrorCode.CommandNotReady, "The supported sensor types are not yet known."); + ZWaveException.Throw(ZWaveErrorCode.CommandNotReady, "The supported sensor types are not yet known."); } if (!SupportedSensorTypes.Contains(sensorType.Value)) { - throw new ZWaveException(ZWaveErrorCode.CommandInvalidArgument, $"Sensor type '{sensorType.Value}' is not supported for this node."); + ZWaveException.Throw(ZWaveErrorCode.CommandInvalidArgument, $"Sensor type '{sensorType.Value}' is not supported for this node."); } if (SupportedScales == null) { - throw new ZWaveException(ZWaveErrorCode.CommandNotReady, "The supported scales are not yet known."); + ZWaveException.Throw(ZWaveErrorCode.CommandNotReady, "The supported scales are not yet known."); } if (scale != null) { if (!SupportedScales[sensorType.Value]!.Contains(scale)) { - throw new ZWaveException(ZWaveErrorCode.CommandInvalidArgument, $"Scale '{scale.Label}' is not supported for this sensor."); + ZWaveException.Throw(ZWaveErrorCode.CommandInvalidArgument, $"Scale '{scale.Label}' is not supported for this sensor."); } scaleId = scale.Id; @@ -160,7 +160,7 @@ public static MultilevelSensorReport Parse(CommandClassFrame frame, ILogger logg if (frame.CommandParameters.Length < 3) { logger.LogWarning("Multilevel Sensor Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Multilevel Sensor Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Multilevel Sensor Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; @@ -178,7 +178,7 @@ public static MultilevelSensorReport Parse(CommandClassFrame frame, ILogger logg "Multilevel Sensor Report frame value size ({ValueSize}) exceeds remaining bytes ({Remaining})", valueSize, frame.CommandParameters.Length - 2); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Multilevel Sensor Report frame is too short for declared value size"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Multilevel Sensor Report frame is too short for declared value size"); } ReadOnlySpan valueBytes = span.Slice(2, valueSize); diff --git a/src/ZWave.CommandClasses/MultilevelSensorCommandClass.SupportedScale.cs b/src/ZWave.CommandClasses/MultilevelSensorCommandClass.SupportedScale.cs index a2aae68..fbd3464 100644 --- a/src/ZWave.CommandClasses/MultilevelSensorCommandClass.SupportedScale.cs +++ b/src/ZWave.CommandClasses/MultilevelSensorCommandClass.SupportedScale.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -26,13 +26,13 @@ public async Task> GetSupportedScalesAsync( bool? isCommandSupported = IsCommandSupported(MultilevelSensorCommand.SupportedScaleGet); if (isCommandSupported == null) { - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.CommandNotReady, "The supported sensor types are not yet known."); } else if (!isCommandSupported.Value) { - throw new ZWaveException(ZWaveErrorCode.CommandNotSupported, "This command is not supported by this node"); + ZWaveException.Throw(ZWaveErrorCode.CommandNotSupported, "This command is not supported by this node"); } else { @@ -42,7 +42,7 @@ public async Task> GetSupportedScalesAsync( if (!SupportedSensorTypes.Contains(sensorType)) { - throw new ZWaveException(ZWaveErrorCode.CommandInvalidArgument, $"Sensor type '{sensorType}' is not supported."); + ZWaveException.Throw(ZWaveErrorCode.CommandInvalidArgument, $"Sensor type '{sensorType}' is not supported."); } var command = MultilevelSensorSupportedScaleGetCommand.Create(sensorType); @@ -98,7 +98,7 @@ public static (MultilevelSensorType SensorType, IReadOnlySet Parse(CommandClassFrame frame, if (frame.CommandParameters.Length < 1) { logger.LogWarning("Multilevel Sensor Supported Sensor Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Multilevel Sensor Supported Sensor Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Multilevel Sensor Supported Sensor Report frame is too short"); } // As per the spec, bit 0 corresponds to Sensor Type 0x01, so offset by 1. diff --git a/src/ZWave.CommandClasses/MultilevelSwitchCommandClass.Report.cs b/src/ZWave.CommandClasses/MultilevelSwitchCommandClass.Report.cs index 2f81e8e..3703eee 100644 --- a/src/ZWave.CommandClasses/MultilevelSwitchCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/MultilevelSwitchCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -125,7 +125,7 @@ public static MultilevelSwitchReport Parse(CommandClassFrame frame, ILogger logg if (frame.CommandParameters.Length < 1) { logger.LogWarning("Multilevel Switch Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Multilevel Switch Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Multilevel Switch Report frame is too short"); } GenericValue currentValue = frame.CommandParameters.Span[0]; diff --git a/src/ZWave.CommandClasses/MultilevelSwitchCommandClass.Supported.cs b/src/ZWave.CommandClasses/MultilevelSwitchCommandClass.Supported.cs index 83375ef..8b96d9e 100644 --- a/src/ZWave.CommandClasses/MultilevelSwitchCommandClass.Supported.cs +++ b/src/ZWave.CommandClasses/MultilevelSwitchCommandClass.Supported.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -60,7 +60,7 @@ public static MultilevelSwitchType Parse(CommandClassFrame frame, ILogger logger if (frame.CommandParameters.Length < 1) { logger.LogWarning("Multilevel Switch Supported Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Multilevel Switch Supported Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Multilevel Switch Supported Report frame is too short"); } return (MultilevelSwitchType)(frame.CommandParameters.Span[0] & 0b0001_1111); diff --git a/src/ZWave.CommandClasses/NotificationCommandClass.EventSupported.cs b/src/ZWave.CommandClasses/NotificationCommandClass.EventSupported.cs index 4cf12f1..f7ac68a 100644 --- a/src/ZWave.CommandClasses/NotificationCommandClass.EventSupported.cs +++ b/src/ZWave.CommandClasses/NotificationCommandClass.EventSupported.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -79,7 +79,7 @@ public static SupportedNotificationEvents Parse(CommandClassFrame frame, ILogger if (frame.CommandParameters.Length < 2) { logger.LogWarning("Notification Event Supported Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Notification Event Supported Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Notification Event Supported Report frame is too short"); } NotificationType notificationType = (NotificationType)frame.CommandParameters.Span[0]; @@ -90,7 +90,7 @@ public static SupportedNotificationEvents Parse(CommandClassFrame frame, ILogger { logger.LogWarning("Notification Event Supported Report bitmask is truncated (expected {Expected}, got {Actual} bytes)", numBitMasks, frame.CommandParameters.Length - 2); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Notification Event Supported Report bitmask is truncated"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Notification Event Supported Report bitmask is truncated"); } HashSet supportedNotificationEvents = []; diff --git a/src/ZWave.CommandClasses/NotificationCommandClass.Report.cs b/src/ZWave.CommandClasses/NotificationCommandClass.Report.cs index 293f8be..a0b6115 100644 --- a/src/ZWave.CommandClasses/NotificationCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/NotificationCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -185,7 +185,7 @@ public static NotificationReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 2) { logger.LogWarning("Notification Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Notification Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Notification Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/NotificationCommandClass.Supported.cs b/src/ZWave.CommandClasses/NotificationCommandClass.Supported.cs index ecc9b8f..69714f6 100644 --- a/src/ZWave.CommandClasses/NotificationCommandClass.Supported.cs +++ b/src/ZWave.CommandClasses/NotificationCommandClass.Supported.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -102,7 +102,7 @@ public static SupportedNotifications Parse(CommandClassFrame frame, ILogger logg if (frame.CommandParameters.Length < 1) { logger.LogWarning("Notification Supported Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Notification Supported Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Notification Supported Report frame is too short"); } bool supportsV1Alarm = (frame.CommandParameters.Span[0] & 0b1000_0000) != 0; @@ -113,7 +113,7 @@ public static SupportedNotifications Parse(CommandClassFrame frame, ILogger logg { logger.LogWarning("Notification Supported Report bitmask is truncated (expected {Expected}, got {Actual} bytes)", numBitMasks, frame.CommandParameters.Length - 1); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Notification Supported Report bitmask is truncated"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Notification Supported Report bitmask is truncated"); } HashSet supportedNotificationTypes = BitMaskHelper.ParseBitMask(frame.CommandParameters.Span.Slice(1, numBitMasks)); diff --git a/src/ZWave.CommandClasses/PowerlevelCommandClass.Powerlevel.cs b/src/ZWave.CommandClasses/PowerlevelCommandClass.Powerlevel.cs index eaa08c9..ed0f803 100644 --- a/src/ZWave.CommandClasses/PowerlevelCommandClass.Powerlevel.cs +++ b/src/ZWave.CommandClasses/PowerlevelCommandClass.Powerlevel.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -184,7 +184,7 @@ public static PowerlevelReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 2) { logger.LogWarning("Powerlevel Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Powerlevel Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Powerlevel Report frame is too short"); } Powerlevel powerlevel = (Powerlevel)frame.CommandParameters.Span[0]; diff --git a/src/ZWave.CommandClasses/PowerlevelCommandClass.TestNode.cs b/src/ZWave.CommandClasses/PowerlevelCommandClass.TestNode.cs index 8d9f322..843eaa6 100644 --- a/src/ZWave.CommandClasses/PowerlevelCommandClass.TestNode.cs +++ b/src/ZWave.CommandClasses/PowerlevelCommandClass.TestNode.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -82,7 +82,7 @@ public async Task TestNodeSetAsync( if (testNode.FrequentListeningMode != FrequentListeningMode.None) { - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.CommandInvalidArgument, $"The test node {testNodeId} is FLiRS and cannot be used for a Powerlevel test"); } @@ -177,7 +177,7 @@ public PowerlevelTestNodeReportCommand(CommandClassFrame frame) if (frame.CommandParameters.Length < 4) { logger.LogWarning("Powerlevel Test Node Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Powerlevel Test Node Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Powerlevel Test Node Report frame is too short"); } ushort nodeId = frame.CommandParameters.Span[0]; diff --git a/src/ZWave.CommandClasses/SupervisionCommandClass.Report.cs b/src/ZWave.CommandClasses/SupervisionCommandClass.Report.cs index c6a18d2..6eaf704 100644 --- a/src/ZWave.CommandClasses/SupervisionCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/SupervisionCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -150,7 +150,7 @@ public static SupervisionGet Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 3) { logger.LogWarning("Supervision Get frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Supervision Get frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Supervision Get frame is too short"); } ReadOnlySpan parameters = frame.CommandParameters.Span; @@ -164,7 +164,7 @@ public static SupervisionGet Parse(CommandClassFrame frame, ILogger logger) "Supervision Get frame has invalid encapsulated command length ({EncapLength} bytes, available {Available})", encapsulatedLength, frame.CommandParameters.Length - 2); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Supervision Get frame has invalid encapsulated command length"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Supervision Get frame has invalid encapsulated command length"); } CommandClassFrame encapsulatedFrame = new CommandClassFrame(frame.CommandParameters.Slice(2, encapsulatedLength)); @@ -227,7 +227,7 @@ public static SupervisionReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 3) { logger.LogWarning("Supervision Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Supervision Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Supervision Report frame is too short"); } ReadOnlySpan parameters = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/TimeCommandClass.Date.cs b/src/ZWave.CommandClasses/TimeCommandClass.Date.cs index fc07f09..f7a02a2 100644 --- a/src/ZWave.CommandClasses/TimeCommandClass.Date.cs +++ b/src/ZWave.CommandClasses/TimeCommandClass.Date.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -100,7 +100,7 @@ public static DateOnly Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 4) { logger.LogWarning("Date Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Date Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Date Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; @@ -115,7 +115,8 @@ public static DateOnly Parse(CommandClassFrame frame, ILogger logger) catch (ArgumentOutOfRangeException) { logger.LogWarning("Date Report has invalid date values (year={Year}, month={Month}, day={Day})", year, month, day); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Date Report has invalid date values"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Date Report has invalid date values"); + return default; } } } diff --git a/src/ZWave.CommandClasses/TimeCommandClass.Time.cs b/src/ZWave.CommandClasses/TimeCommandClass.Time.cs index d4920c5..0c4abdb 100644 --- a/src/ZWave.CommandClasses/TimeCommandClass.Time.cs +++ b/src/ZWave.CommandClasses/TimeCommandClass.Time.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -146,7 +146,7 @@ public static TimeReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 3) { logger.LogWarning("Time Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Time Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Time Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; @@ -163,7 +163,8 @@ public static TimeReport Parse(CommandClassFrame frame, ILogger logger) catch (ArgumentOutOfRangeException) { logger.LogWarning("Time Report has invalid time values (hour={Hour}, minute={Minute}, second={Second})", hour, minute, second); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Time Report has invalid time values"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Time Report has invalid time values"); + return default; } } } diff --git a/src/ZWave.CommandClasses/TimeCommandClass.TimeOffset.cs b/src/ZWave.CommandClasses/TimeCommandClass.TimeOffset.cs index 254fe53..e5f21a5 100644 --- a/src/ZWave.CommandClasses/TimeCommandClass.TimeOffset.cs +++ b/src/ZWave.CommandClasses/TimeCommandClass.TimeOffset.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -173,7 +173,7 @@ public static TimeOffsetReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 9) { logger.LogWarning("Time Offset Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Time Offset Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Time Offset Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/TimeParametersCommandClass.cs b/src/ZWave.CommandClasses/TimeParametersCommandClass.cs index d4f2058..5cdbda2 100644 --- a/src/ZWave.CommandClasses/TimeParametersCommandClass.cs +++ b/src/ZWave.CommandClasses/TimeParametersCommandClass.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -175,7 +175,7 @@ public static DateTime Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 7) { logger.LogWarning("Time Parameters Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Time Parameters Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Time Parameters Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; @@ -200,7 +200,8 @@ public static DateTime Parse(CommandClassFrame frame, ILogger logger) hour, minute, second); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Time Parameters Report has invalid date/time values"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Time Parameters Report has invalid date/time values"); + return default; } } } diff --git a/src/ZWave.CommandClasses/VersionCommandClass.Capabilities.cs b/src/ZWave.CommandClasses/VersionCommandClass.Capabilities.cs index ebf9d0b..0a5af8e 100644 --- a/src/ZWave.CommandClasses/VersionCommandClass.Capabilities.cs +++ b/src/ZWave.CommandClasses/VersionCommandClass.Capabilities.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -96,7 +96,7 @@ public static VersionCapabilities Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 1) { logger.LogWarning("Version Capabilities Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Version Capabilities Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Version Capabilities Report frame is too short"); } return (VersionCapabilities)frame.CommandParameters.Span[0]; diff --git a/src/ZWave.CommandClasses/VersionCommandClass.CommandClass.cs b/src/ZWave.CommandClasses/VersionCommandClass.CommandClass.cs index 0f42934..33ef81e 100644 --- a/src/ZWave.CommandClasses/VersionCommandClass.CommandClass.cs +++ b/src/ZWave.CommandClasses/VersionCommandClass.CommandClass.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -59,7 +59,7 @@ public static (CommandClassId RequestedCommandClass, byte CommandClassVersion) P if (frame.CommandParameters.Length < 2) { logger.LogWarning("Version Command Class Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Version Command Class Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Version Command Class Report frame is too short"); } return ((CommandClassId)frame.CommandParameters.Span[0], frame.CommandParameters.Span[1]); diff --git a/src/ZWave.CommandClasses/VersionCommandClass.Migration.cs b/src/ZWave.CommandClasses/VersionCommandClass.Migration.cs index cedf6f3..8bf2dd2 100644 --- a/src/ZWave.CommandClasses/VersionCommandClass.Migration.cs +++ b/src/ZWave.CommandClasses/VersionCommandClass.Migration.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -165,7 +165,7 @@ public static VersionMigrationCapabilities Parse(CommandClassFrame frame, ILogge if (frame.CommandParameters.Length < 1) { logger.LogWarning("Version Migration Capabilities Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Version Migration Capabilities Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Version Migration Capabilities Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; @@ -183,7 +183,7 @@ public static VersionMigrationCapabilities Parse(CommandClassFrame frame, ILogge "Version Migration Capabilities Report declares {Count} operations but only has {Length} bytes of payload", count, frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Version Migration Capabilities Report payload is too short for declared operation count"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Version Migration Capabilities Report payload is too short for declared operation count"); } operations = new MigrationOperationId[count]; @@ -258,7 +258,7 @@ public static VersionMigrationReport Parse(CommandClassFrame frame, ILogger logg if (frame.CommandParameters.Length < 4) { logger.LogWarning("Version Migration Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Version Migration Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Version Migration Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/VersionCommandClass.Report.cs b/src/ZWave.CommandClasses/VersionCommandClass.Report.cs index 7f7fcc3..7fdb7e7 100644 --- a/src/ZWave.CommandClasses/VersionCommandClass.Report.cs +++ b/src/ZWave.CommandClasses/VersionCommandClass.Report.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -161,7 +161,7 @@ public static VersionReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 5) { logger.LogWarning("Version Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Version Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Version Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; @@ -183,7 +183,7 @@ public static VersionReport Parse(CommandClassFrame frame, ILogger logger) "Version Report declares {Count} additional firmware targets but payload is too short ({Length} bytes)", declaredAdditionalFirmware, frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Version Report payload is too short for declared firmware count"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Version Report payload is too short for declared firmware count"); } numFirmwareVersions += declaredAdditionalFirmware; diff --git a/src/ZWave.CommandClasses/VersionCommandClass.ZWaveSoftware.cs b/src/ZWave.CommandClasses/VersionCommandClass.ZWaveSoftware.cs index 767f097..b0b5bbe 100644 --- a/src/ZWave.CommandClasses/VersionCommandClass.ZWaveSoftware.cs +++ b/src/ZWave.CommandClasses/VersionCommandClass.ZWaveSoftware.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -124,7 +124,7 @@ public static VersionSoftwareInfo Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 23) { logger.LogWarning("Version Z-Wave Software Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Version Z-Wave Software Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Version Z-Wave Software Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/WakeUpCommandClass.Interval.cs b/src/ZWave.CommandClasses/WakeUpCommandClass.Interval.cs index a82eb74..01b68ca 100644 --- a/src/ZWave.CommandClasses/WakeUpCommandClass.Interval.cs +++ b/src/ZWave.CommandClasses/WakeUpCommandClass.Interval.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -122,7 +122,7 @@ public static WakeUpInterval Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 4) { logger.LogWarning("Wake Up Interval Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Wake Up Interval Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Wake Up Interval Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/WakeUpCommandClass.IntervalCapabilities.cs b/src/ZWave.CommandClasses/WakeUpCommandClass.IntervalCapabilities.cs index 68e224c..fa729a9 100644 --- a/src/ZWave.CommandClasses/WakeUpCommandClass.IntervalCapabilities.cs +++ b/src/ZWave.CommandClasses/WakeUpCommandClass.IntervalCapabilities.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -89,7 +89,7 @@ public static WakeUpIntervalCapabilities Parse(CommandClassFrame frame, ILogger if (frame.CommandParameters.Length < 12) { logger.LogWarning("Wake Up Interval Capabilities Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Wake Up Interval Capabilities Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Wake Up Interval Capabilities Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; diff --git a/src/ZWave.CommandClasses/ZWavePlusInfoCommandClass.cs b/src/ZWave.CommandClasses/ZWavePlusInfoCommandClass.cs index 8ca4331..600ae3a 100644 --- a/src/ZWave.CommandClasses/ZWavePlusInfoCommandClass.cs +++ b/src/ZWave.CommandClasses/ZWavePlusInfoCommandClass.cs @@ -1,4 +1,4 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace ZWave.CommandClasses; @@ -216,7 +216,7 @@ public static ZWavePlusInfoReport Parse(CommandClassFrame frame, ILogger logger) if (frame.CommandParameters.Length < 7) { logger.LogWarning("Z-Wave Plus Info Report frame is too short ({Length} bytes)", frame.CommandParameters.Length); - throw new ZWaveException(ZWaveErrorCode.InvalidPayload, "Z-Wave Plus Info Report frame is too short"); + ZWaveException.Throw(ZWaveErrorCode.InvalidPayload, "Z-Wave Plus Info Report frame is too short"); } ReadOnlySpan span = frame.CommandParameters.Span; diff --git a/src/ZWave.Protocol/ZWave.Protocol.csproj b/src/ZWave.Protocol/ZWave.Protocol.csproj index 00b9359..1f6a279 100644 --- a/src/ZWave.Protocol/ZWave.Protocol.csproj +++ b/src/ZWave.Protocol/ZWave.Protocol.csproj @@ -2,6 +2,11 @@ net10.0 + ZWave + + + + diff --git a/src/ZWave.Protocol/ZWaveException.cs b/src/ZWave.Protocol/ZWaveException.cs index 1b48535..d72224f 100644 --- a/src/ZWave.Protocol/ZWaveException.cs +++ b/src/ZWave.Protocol/ZWaveException.cs @@ -1,4 +1,4 @@ -using System.Runtime.Serialization; +using System.Diagnostics.CodeAnalysis; namespace ZWave; @@ -7,32 +7,35 @@ namespace ZWave; /// public sealed class ZWaveException : Exception { - /// - /// Initializes a new instance of the class with the specified error code, message, and inner exception. - /// - public ZWaveException(ZWaveErrorCode errorCode, string message, Exception innerException) + private ZWaveException(ZWaveErrorCode errorCode, string message, Exception? innerException = null) : base(message, innerException) { ErrorCode = errorCode; } /// - /// Initializes a new instance of the class with the specified error code and message. + /// Gets the error code identifying the class of error. /// - public ZWaveException(ZWaveErrorCode errorCode, string message) - : base(message) - { - ErrorCode = errorCode; - } + public ZWaveErrorCode ErrorCode { get; } - // Serialization constructor - private ZWaveException(SerializationInfo info, StreamingContext context) - { + /// + /// Throws a with the specified error code and message. + /// + [DoesNotReturn] + public static void Throw(ZWaveErrorCode errorCode, string message) + => throw new ZWaveException(errorCode, message); - } + /// + /// Throws a with the specified error code, message, and inner exception. + /// + [DoesNotReturn] + public static void Throw(ZWaveErrorCode errorCode, string message, Exception innerException) + => throw new ZWaveException(errorCode, message, innerException); /// - /// Gets the error code identifying the class of error. + /// Creates a without throwing it. + /// For use with and similar APIs. /// - public ZWaveErrorCode ErrorCode { get; } + internal static ZWaveException Create(ZWaveErrorCode errorCode, string message) + => new(errorCode, message); } diff --git a/src/ZWave.Serial/ZWaveSerialPortCoordinator.cs b/src/ZWave.Serial/ZWaveSerialPortCoordinator.cs index 501d415..72654b5 100644 --- a/src/ZWave.Serial/ZWaveSerialPortCoordinator.cs +++ b/src/ZWave.Serial/ZWaveSerialPortCoordinator.cs @@ -57,10 +57,14 @@ public ZWaveSerialPortCoordinator( ChannelReader dataFrameSendChannelReader, ChannelWriter dataFrameReceiveChannelWriter) { - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + ArgumentNullException.ThrowIfNull(logger); + ArgumentNullException.ThrowIfNull(dataFrameSendChannelReader); + ArgumentNullException.ThrowIfNull(dataFrameReceiveChannelWriter); + + _logger = logger; _serialPort = CreateSerialPort(portName); - _dataFrameSendChannelReader = dataFrameSendChannelReader ?? throw new ArgumentNullException(nameof(dataFrameSendChannelReader)); - _dataFrameReceiveChannelWriter = dataFrameReceiveChannelWriter ?? throw new ArgumentNullException(nameof(dataFrameReceiveChannelWriter)); + _dataFrameSendChannelReader = dataFrameSendChannelReader; + _dataFrameReceiveChannelWriter = dataFrameReceiveChannelWriter; _serialPort.Open(); _logger.LogSerialApiPortOpened(_serialPort.PortName); @@ -77,10 +81,7 @@ public ZWaveSerialPortCoordinator( private static SerialPort CreateSerialPort(string portName) { - if (string.IsNullOrEmpty(portName)) - { - throw new ArgumentNullException(nameof(portName)); - } + ArgumentException.ThrowIfNullOrEmpty(portName); // INS12350 4.2.1 defines the serial port settings var serialPort = new SerialPort( @@ -355,7 +356,7 @@ private async Task WriteAsync() _commLock.Release(); } - transmission.TransmissionComplete.SetException(new ZWaveException(ZWaveErrorCode.CommandSendFailed, "Command failed to send")); + transmission.TransmissionComplete.SetException(ZWaveException.Create(ZWaveErrorCode.CommandSendFailed, "Command failed to send")); } } } diff --git a/src/ZWave/CommandClassCollection.cs b/src/ZWave/CommandClassCollection.cs index 2cb4f71..57c9cd2 100644 --- a/src/ZWave/CommandClassCollection.cs +++ b/src/ZWave/CommandClassCollection.cs @@ -45,9 +45,14 @@ internal IReadOnlyDictionary CommandClasses } internal CommandClass GetCommandClass(CommandClassId commandClassId) - => !TryGetCommandClass(commandClassId, out CommandClass? commandClass) - ? throw new ZWaveException(ZWaveErrorCode.CommandClassNotImplemented, $"The command class {commandClassId} is not supported.") - : commandClass; + { + if (!TryGetCommandClass(commandClassId, out CommandClass? commandClass)) + { + ZWaveException.Throw(ZWaveErrorCode.CommandClassNotImplemented, $"The command class {commandClassId} is not supported."); + } + + return commandClass; + } internal TCommandClass GetCommandClass() where TCommandClass : CommandClass diff --git a/src/ZWave/Controller.cs b/src/ZWave/Controller.cs index 71061d6..1c41127 100644 --- a/src/ZWave/Controller.cs +++ b/src/ZWave/Controller.cs @@ -196,7 +196,7 @@ public async Task IdentifyAsync(CancellationToken cancellationToken) // The command was supported and this subcommand should always be supported, so this should never happen in practice. if (!getSupportedSetupCommandsResponse.WasSubcommandSupported) { - throw new ZWaveException(ZWaveErrorCode.ControllerInitializationFailed, "SerialApiSetup.GetSupportedCommands was not supported"); + ZWaveException.Throw(ZWaveErrorCode.ControllerInitializationFailed, "SerialApiSetup.GetSupportedCommands was not supported"); } SupportedSerialApiSetupSubcommands = getSupportedSetupCommandsResponse.SupportedSubcommands; @@ -233,7 +233,7 @@ public async Task IdentifyAsync(CancellationToken cancellationToken) // We checked that this was supported, so this should never happen in practice. if (!setTxStatusReportResponse.WasSubcommandSupported) { - throw new ZWaveException(ZWaveErrorCode.ControllerInitializationFailed, "SerialApiSetup.SetTxStatusReport was not supported"); + ZWaveException.Throw(ZWaveErrorCode.ControllerInitializationFailed, "SerialApiSetup.SetTxStatusReport was not supported"); } _logger.LogEnableTxStatusReport(setTxStatusReportResponse.Success); @@ -270,7 +270,7 @@ public async Task IdentifyAsync(CancellationToken cancellationToken) if (setSucNodeIdCallback.SetSucNodeIdStatus != SetSucNodeIdStatus.Succeeded) { - throw new ZWaveException(ZWaveErrorCode.ControllerInitializationFailed, "SetSucNodeId failed"); + ZWaveException.Throw(ZWaveErrorCode.ControllerInitializationFailed, "SetSucNodeId failed"); } SucNodeId = NodeId; @@ -306,7 +306,7 @@ public async Task IdentifyAsync(CancellationToken cancellationToken) } catch (Exception ex) { - throw new ZWaveException(ZWaveErrorCode.ControllerInitializationFailed, "Failed to initialize the controller", ex); + ZWaveException.Throw(ZWaveErrorCode.ControllerInitializationFailed, "Failed to initialize the controller", ex); } } diff --git a/src/ZWave/Driver.cs b/src/ZWave/Driver.cs index 68c712d..589da82 100644 --- a/src/ZWave/Driver.cs +++ b/src/ZWave/Driver.cs @@ -58,12 +58,10 @@ private record struct UnresolvedCallbackKey(CommandId CommandId, byte SessionId) private Driver(ILogger logger, string portName) { - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + ArgumentNullException.ThrowIfNull(logger); + ArgumentException.ThrowIfNullOrEmpty(portName); - if (string.IsNullOrEmpty(portName)) - { - throw new ArgumentNullException(nameof(portName)); - } + _logger = logger; // We can assume a single reader based on the implementation of the serial port coordinator. The writer is the driver, which may be called by multiple callers. Channel dataFrameSendChannel = Channel.CreateUnbounded(new UnboundedChannelOptions { SingleReader = true, SingleWriter = false }); @@ -339,7 +337,7 @@ private async Task InitializeAsync(CancellationToken cancellationToken) } catch (Exception ex) { - throw new ZWaveException(ZWaveErrorCode.DriverInitializationFailed, "Soft reset failed", ex); + ZWaveException.Throw(ZWaveErrorCode.DriverInitializationFailed, "Soft reset failed", ex); } await Controller.IdentifyAsync(cancellationToken).ConfigureAwait(false); @@ -451,7 +449,7 @@ internal async Task SendCommandExpectingCallbackAsync( .ConfigureAwait(false); if (!response.WasRequestAccepted) { - throw new ZWaveException(ZWaveErrorCode.CommandFailed, "Response status indicated failure"); + ZWaveException.Throw(ZWaveErrorCode.CommandFailed, "Response status indicated failure"); } TaskCompletionSource tcs = new TaskCompletionSource(); @@ -615,7 +613,8 @@ private async Task AwaitCallbackAsync( catch (TimeoutException) { RemoveUnresolvedCallback(callbackKey); - throw new ZWaveException(ZWaveErrorCode.CallbackTimeout, $"Timed out waiting for callback for {callbackKey.CommandId}"); + ZWaveException.Throw(ZWaveErrorCode.CallbackTimeout, $"Timed out waiting for callback for {callbackKey.CommandId}"); + return default!; } catch { @@ -639,7 +638,7 @@ private async Task SendFrameAsync(DataFrame request, CancellationToken cancellat IReadOnlySet? supportedCommandIds = Controller.SupportedCommandIds; if (supportedCommandIds != null && !supportedCommandIds.Contains(request.CommandId)) { - throw new ZWaveException( + ZWaveException.Throw( ZWaveErrorCode.SerialApiCommandNotSupported, $"The serial API command {request.CommandId} is not supported by the controller"); } diff --git a/src/ZWave/Node.cs b/src/ZWave/Node.cs index 39bc4ad..acd6316 100644 --- a/src/ZWave/Node.cs +++ b/src/ZWave/Node.cs @@ -35,9 +35,12 @@ public sealed class Node : INode internal Node(ushort id, Driver driver, ILogger logger) { + ArgumentNullException.ThrowIfNull(driver); + ArgumentNullException.ThrowIfNull(logger); + Id = id; - _driver = driver ?? throw new ArgumentNullException(nameof(driver)); - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + _driver = driver; + _logger = logger; _commandClassCollection = new CommandClassCollection(driver, this, logger); }