Summary
Replace all throw statements throughout CSLibrary2026 with a return-error pattern. Introduce structured error/result types so callers can handle failures gracefully without risking unhandled exceptions or application crashes.
Background
Throwing exceptions at runtime is dangerous in library code consumed by apps:
- Unhandled exceptions crash the application
- Callers have no compile-time safety net for handling specific failure modes
- Exceptions cannot be awaited cleanly in async contexts without try/catch wrappers everywhere
- Library should communicate failure as a return value, not an exception
Requirement
1. Audit All throw Statements
Search the entire codebase for throw statements in production (non-test) code:
grep -rn "throw new" Source/ --include="*.cs" | grep -v "throw new NotImplementedException\|throw new ExecutionEngineException\|#if DEBUG\|#if NETCFDESIGNTIME\|Test\|Mock"
Categorize each throw into:
- Replaceable — should return an error instead
- Acceptable —
throw new NotImplementedException() for stubs is fine
- Critical —
throw for truly unrecoverable/programming errors (e.g., InvalidOperationException on misuse of internal state)
2. Define Structured Error Types
Create a result/error enum or class in a shared location (e.g., CSLibrary.Results or CSLibrary.ErrorCodes):
namespace CSLibrary
{
/// <summary>
/// Result codes returned by CSLibrary operations.
/// </summary>
public enum Result
{
OK = 0,
NOT_INITIALIZED = 1,
NOT_SUPPORTED = 2,
DEVICE_NOT_CONNECTED = 3,
TRANSPORT_ERROR = 4,
TIMEOUT = 5,
INVALID_PARAMETER = 6,
ALREADY_INITIALIZED = 7,
PERMISSION_DENIED = 8,
INTERNAL_ERROR = 99,
}
}
3. Replace throw with Return-Error Pattern
For each replaceable throw, change the method signature to return Result (or a more specific enum) and return the appropriate error code:
// Instead of:
public void Connect(string address)
{
if (string.IsNullOrEmpty(address))
throw new ArgumentNullException(nameof(address));
// ...
}
// Do:
public Result Connect(string address)
{
if (string.IsNullOrEmpty(address))
return Result.INVALID_PARAMETER;
// ...
return Result.OK;
}
4. Preserved throw Cases
The following throw patterns are acceptable and should NOT be changed:
throw new NotImplementedException() — for stub methods not yet implemented
throw new InvalidOperationException(...) in constructor/init — for truly unrecoverable misconfiguration
throw inside #if DEBUG blocks
throw inside unit test files
Scope
Files to audit (all .cs under Source/):
Source/HAL/ — all HAL implementations (TCP, BLE, etc.)
Source/RFIDReader/ — all RFID reader API classes
Source/Transport/ — transport layer
Source/Notification/ — notification handling
Source/BarcodeReader/ — barcode reader HAL
Source/Properties/ — assembly attributes (no changes expected)
Files Expected to Change
Source/HAL/TCPIP/NetFinder.cs — may have throw statements
Source/HAL/TCPIP/ClassDeviceFinder.cs — may have throw statements
Source/HAL/Plugin.BLE/DeviceFinder.cs — may have throw statements
- Various
Source/RFIDReader/ files — may have throw for invalid parameters or transport errors
Acceptance Criteria
Notes
#if ANDROID, #if DEBUG, #if BIGENDIAN guards are acceptable and should not be modified
- All content must be English
- Keep the changes focused: only replace
throw with return-error, do not refactor other logic at the same time
Summary
Replace all
throwstatements throughout CSLibrary2026 with a return-error pattern. Introduce structured error/result types so callers can handle failures gracefully without risking unhandled exceptions or application crashes.Background
Throwing exceptions at runtime is dangerous in library code consumed by apps:
Requirement
1. Audit All
throwStatementsSearch the entire codebase for
throwstatements in production (non-test) code:Categorize each
throwinto:throw new NotImplementedException()for stubs is finethrowfor truly unrecoverable/programming errors (e.g.,InvalidOperationExceptionon misuse of internal state)2. Define Structured Error Types
Create a result/error enum or class in a shared location (e.g.,
CSLibrary.ResultsorCSLibrary.ErrorCodes):3. Replace
throwwith Return-Error PatternFor each replaceable
throw, change the method signature to returnResult(or a more specific enum) and return the appropriate error code:4. Preserved
throwCasesThe following
throwpatterns are acceptable and should NOT be changed:throw new NotImplementedException()— for stub methods not yet implementedthrow new InvalidOperationException(...)in constructor/init — for truly unrecoverable misconfigurationthrowinside#if DEBUGblocksthrowinside unit test filesScope
Files to audit (all
.csunderSource/):Source/HAL/— all HAL implementations (TCP, BLE, etc.)Source/RFIDReader/— all RFID reader API classesSource/Transport/— transport layerSource/Notification/— notification handlingSource/BarcodeReader/— barcode reader HALSource/Properties/— assembly attributes (no changes expected)Files Expected to Change
Source/HAL/TCPIP/NetFinder.cs— may havethrowstatementsSource/HAL/TCPIP/ClassDeviceFinder.cs— may havethrowstatementsSource/HAL/Plugin.BLE/DeviceFinder.cs— may havethrowstatementsSource/RFIDReader/files — may havethrowfor invalid parameters or transport errorsAcceptance Criteria
throwstatements categorizedResult(or similar) enum created in appropriate namespacethrowstatements converted to returnResulterror codesdotnet build -c Releasesucceeds with 0 errorsthrow new Exceptionorthrow new ArgumentNullExceptionin production HAL/RFIDReader codeNotes
#if ANDROID,#if DEBUG,#if BIGENDIANguards are acceptable and should not be modifiedthrowwith return-error, do not refactor other logic at the same time