using System; using System.Diagnostics.CodeAnalysis; using NModbus.Message; namespace NModbus { #if NET46 using System.Runtime.Serialization; using System.Security.Permissions; #endif /// /// Represents slave errors that occur during communication. /// #if NET46 [Serializable] #endif public class SlaveException : Exception { private const string SlaveAddressPropertyName = "SlaveAdress"; private const string FunctionCodePropertyName = "FunctionCode"; private const string SlaveExceptionCodePropertyName = "SlaveExceptionCode"; [AllowNull] private readonly SlaveExceptionResponse _slaveExceptionResponse; /// /// Initializes a new instance of the class. /// public SlaveException() { } /// /// Initializes a new instance of the class. /// /// The message. public SlaveException(string message) : base(message) { } /// /// Initializes a new instance of the class. /// /// The message. /// The inner exception. public SlaveException(string message, Exception innerException) : base(message, innerException) { } internal SlaveException(SlaveExceptionResponse slaveExceptionResponse) { _slaveExceptionResponse = slaveExceptionResponse; } [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Used by test code.")] internal SlaveException(string message, SlaveExceptionResponse slaveExceptionResponse) : base(message) { _slaveExceptionResponse = slaveExceptionResponse; } #if NET46 /// /// Initializes a new instance of the class. /// /// /// The that holds the serialized /// object data about the exception being thrown. /// /// /// The that contains contextual /// information about the source or destination. /// /// /// The class name is null or /// is zero (0). /// /// The info parameter is null. protected SlaveException(SerializationInfo info, StreamingContext context) : base(info, context) { if (info != null) { _slaveExceptionResponse = new SlaveExceptionResponse( info.GetByte(SlaveAddressPropertyName), info.GetByte(FunctionCodePropertyName), info.GetByte(SlaveExceptionCodePropertyName)); } } #endif /// /// Gets a message that describes the current exception. /// /// /// The error message that explains the reason for the exception, or an empty string. /// public override string Message { get { string responseString; responseString = _slaveExceptionResponse != null ? string.Concat(Environment.NewLine, _slaveExceptionResponse) : string.Empty; return string.Concat(base.Message, responseString); } } /// /// Gets the response function code that caused the exception to occur, or 0. /// /// The function code. public byte FunctionCode => _slaveExceptionResponse != null ? _slaveExceptionResponse.FunctionCode : (byte)0; /// /// Gets the slave exception code, or 0. /// /// The slave exception code. public byte SlaveExceptionCode => _slaveExceptionResponse != null ? _slaveExceptionResponse.SlaveExceptionCode : (byte)0; /// /// Gets the slave address, or 0. /// /// The slave address. public byte SlaveAddress => _slaveExceptionResponse != null ? _slaveExceptionResponse.SlaveAddress : (byte)0; #if NET46 /// /// When overridden in a derived class, sets the /// with information about the exception. /// /// /// The that holds the serialized /// object data about the exception being thrown. /// /// /// The that contains contextual /// information about the source or destination. /// /// The info parameter is a null reference (Nothing in Visual Basic). /// /// /// /// [SecurityPermissionAttribute(SecurityAction.Demand, SerializationFormatter = true)] [SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods", Justification = "Argument info is validated, rule does not understand AND condition.")] public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); if (info != null && _slaveExceptionResponse != null) { info.AddValue(SlaveAddressPropertyName, _slaveExceptionResponse.SlaveAddress); info.AddValue(FunctionCodePropertyName, _slaveExceptionResponse.FunctionCode); info.AddValue(SlaveExceptionCodePropertyName, _slaveExceptionResponse.SlaveExceptionCode); } } #endif } }