using System; using System.Runtime.InteropServices; namespace Unosquare.RaspberryIO.Abstractions.Native { /// <summary> /// Represents a low-level exception, typically thrown when return codes from a /// low-level operation is non-zero or in some cases when it is less than zero. /// </summary> /// <seealso cref="Exception" /> public class HardwareException : Exception { /// <summary> /// Initializes a new instance of the <see cref="HardwareException"/> class. /// </summary> /// <param name="errorCode">The error code.</param> /// <param name="component">The component.</param> public HardwareException(Int32 errorCode, String component) : base($"A hardware exception occurred. Error Code: {errorCode}") { this.ExtendedMessage = null; try { this.ExtendedMessage = Standard.Strerror(errorCode); } catch { // Ignore } this.ErrorCode = errorCode; this.Component = component; } /// <summary> /// Gets the error code. /// </summary> /// <value> /// The error code. /// </value> public Int32 ErrorCode { get; } /// <summary> /// Gets the component. /// </summary> /// <value> /// The component. /// </value> public String Component { get; } /// <summary> /// Gets the extended message (could be null). /// </summary> /// <value> /// The extended message. /// </value> public String? ExtendedMessage { get; } /// <summary> /// Throws a new instance of a hardware error by retrieving the last error number (errno). /// </summary> /// <param name="className">Name of the class.</param> /// <param name="methodName">Name of the method.</param> /// <exception cref="HardwareException">When an error thrown by an API call occurs.</exception> public static void Throw(String className, String methodName) => throw new HardwareException(Marshal.GetLastWin32Error(), $"{className}.{methodName}"); /// <inheritdoc /> public override String ToString() => $"{nameof(HardwareException)}{(String.IsNullOrWhiteSpace(this.Component) ? String.Empty : $" on {this.Component}")}: ({this.ErrorCode}) - {this.Message}"; } }