using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Remoting.Messaging; using System.Runtime.Serialization; using System.Security.Permissions; using EOSDigital.SDK; namespace EOSDigital.API { /// /// An Exception that happened while handling the Canon SDK /// [Serializable] public sealed class SDKException : Exception { /// /// The specific SDK error code that happened /// public ErrorCode Error { get; private set; } /// /// Initializes a new instance of the class /// public SDKException() { Error = ErrorCode.INTERNAL_ERROR; } /// /// Initializes a new instance of the class with a specified error code /// /// The SDK error code of the error that happened public SDKException(ErrorCode Error) : base(Error.ToString()) { this.Error = Error; } /// /// Initializes a new instance of the class with a specified error message /// /// The error message that explains the reason for the exception. public SDKException(string message) : base(message) { Error = ErrorCode.INTERNAL_ERROR; } /// /// Initializes a new instance of the class with a specified /// error message and a reference to the inner exception that is the cause of /// this exception /// /// The error message that explains the reason for the exception /// The exception that is the cause of the current exception, or a null reference /// (Nothing in Visual Basic) if no inner exception is specified public SDKException(string message, Exception innerException) : base(message, innerException) { Error = ErrorCode.INTERNAL_ERROR; } /// /// Initializes a new instance of the class with a specified error message and error code /// /// The SDK error code of the error that happened /// The error message that explains the reason for the exception public SDKException(string message, ErrorCode Error) : base(message) { this.Error = Error; } /// /// Initializes a new instance of the class with a specified /// error message, error code and a reference to the inner exception that is the cause of /// this exception /// /// The error message that explains the reason for the exception /// The SDK error code of the error that happened /// The exception that is the cause of the current exception, or a null reference /// (Nothing in Visual Basic) if no inner exception is specified. public SDKException(string message, ErrorCode Error, Exception innerException) : base(message, innerException) { this.Error = Error; } /// /// Initializes a new instance of the class with serialized data. /// /// The that holds the serialized /// object data about the exception being thrown. /// The that contains contextual /// information about the source or destination. [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] private SDKException(SerializationInfo info, StreamingContext context) : base(info, context) { Error = (ErrorCode)info.GetUInt32("Error"); } /// /// 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 [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] public override void GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) throw new ArgumentNullException(nameof(info)); info.AddValue("Error", Error); base.GetObjectData(info, context); } } /// /// An Exception that states a problem with the session state of the camera /// [Serializable] public sealed class CameraSessionException : Exception { /// /// Initializes a new instance of the class /// public CameraSessionException() { } /// /// Initializes a new instance of the class with a specified error message /// /// The error message that explains the reason for the exception. public CameraSessionException(string message) : base(message) { } /// /// Initializes a new instance of the class with a specified /// error message and a reference to the inner exception that is the cause of /// this exception /// /// The error message that explains the reason for the exception /// The exception that is the cause of the current exception, or a null reference /// (Nothing in Visual Basic) if no inner exception is specified public CameraSessionException(string message, Exception innerException) : base(message, innerException) { } /// /// Initializes a new instance of the class with serialized data. /// /// The that holds the serialized /// object data about the exception being thrown. /// The that contains contextual /// information about the source or destination. [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] private CameraSessionException(SerializationInfo info, StreamingContext context) : base(info, context) { } /// /// 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 [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] public override void GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) throw new ArgumentNullException(nameof(info)); base.GetObjectData(info, context); } } /// /// An Exception that states a problem with the state of the Canon SDK /// [Serializable] public sealed class SDKStateException : Exception { /// /// Initializes a new instance of the class /// public SDKStateException() { } /// /// Initializes a new instance of the class with a specified error message /// /// The error message that explains the reason for the exception. public SDKStateException(string message) : base(message) { } /// /// Initializes a new instance of the class with a specified /// error message and a reference to the inner exception that is the cause of /// this exception /// /// The error message that explains the reason for the exception /// The exception that is the cause of the current exception, or a null reference /// (Nothing in Visual Basic) if no inner exception is specified public SDKStateException(string message, Exception innerException) : base(message, innerException) { } /// /// Initializes a new instance of the class with serialized data. /// /// The that holds the serialized /// object data about the exception being thrown. /// The that contains contextual /// information about the source or destination. [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] private SDKStateException(SerializationInfo info, StreamingContext context) : base(info, context) { } /// /// 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 [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] public override void GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) throw new ArgumentNullException(nameof(info)); base.GetObjectData(info, context); } } /// /// An Exception that happened while executing on an STA thread /// [Serializable] public sealed class ExecutionException : Exception { /// /// Initializes a new instance of the class with a specified error message /// /// The error message that explains the reason for the exception. public ExecutionException(string message) : base(message) { } /// /// Initializes a new instance of the class with a reference to /// the inner exception that is the cause of this exception /// /// The error message that explains the reason for the exception /// The exception that is the cause of the current exception, or a null reference /// (Nothing in Visual Basic) if no inner exception is specified public ExecutionException(string message, Exception innerException) : base(message, innerException) { } /// /// Initializes a new instance of the class with serialized data. /// /// The that holds the serialized /// object data about the exception being thrown. /// The that contains contextual /// information about the source or destination. [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] private ExecutionException(SerializationInfo info, StreamingContext context) : base(info, context) { } /// /// 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 [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)] public override void GetObjectData(SerializationInfo info, StreamingContext context) { if (info == null) throw new ArgumentNullException(nameof(info)); base.GetObjectData(info, context); } } /// /// Handles errors and provides events for errors (e.g. focus problems or general exceptions) /// public static class ErrorHandler { /// /// If an error happened, that does not break the program, this event is fired (e.g. a focus error) /// public static event SDKExceptionHandler NonSevereErrorHappened; /// /// If an error happened on a thread that does not fall into the non-severe category, this event is fired /// public static event GeneralExceptionHandler SevereErrorHappened; /// /// List of all non-severe errors. Items can be added or removed. /// public static List NonSevereErrors { get; private set; } static ErrorHandler() { NonSevereErrors = new List() { ErrorCode.TAKE_PICTURE_AF_NG, ErrorCode.TAKE_PICTURE_CARD_NG, ErrorCode.TAKE_PICTURE_CARD_PROTECT_NG, ErrorCode.TAKE_PICTURE_LV_REL_PROHIBIT_MODE_NG, ErrorCode.TAKE_PICTURE_MIRROR_UP_NG, ErrorCode.TAKE_PICTURE_MOVIE_CROP_NG, ErrorCode.TAKE_PICTURE_NO_CARD_NG, ErrorCode.TAKE_PICTURE_NO_LENS_NG, ErrorCode.TAKE_PICTURE_SENSOR_CLEANING_NG, ErrorCode.TAKE_PICTURE_SILENCE_NG, ErrorCode.TAKE_PICTURE_SPECIAL_MOVIE_MODE_NG, ErrorCode.TAKE_PICTURE_STROBO_CHARGE_NG, ErrorCode.LENS_COVER_CLOSE, ErrorCode.DEVICE_BUSY, }; } /// /// Checks for an error in SDK calls and checks how to treat it /// /// The sender object /// The return code of the SDK call /// If a severe error is recognized or the /// event is null with a non-severe error, it will be thrown as an exception public static void CheckError(object sender, ErrorCode errorCode) { if (errorCode == ErrorCode.OK) return; else { bool Severe = !NonSevereErrors.Any(t => t == errorCode); var NonSevereErrorHappenedEvent = NonSevereErrorHappened; if (!Severe) Severe = NonSevereErrorHappenedEvent == null; if (Severe) throw new SDKException(errorCode); else NonSevereErrorHappenedEvent.BeginInvoke(sender, errorCode, (a) => { var ar = a as AsyncResult; var invokedMethod = ar.AsyncDelegate as SDKExceptionHandler; invokedMethod.EndInvoke(a); }, null); } } /// /// Checks for an error in SDK calls and throws an exception if it's not /// /// The return code of the SDK call /// If is something other than public static void CheckError(ErrorCode errorCode) { if (errorCode != ErrorCode.OK) throw new SDKException(errorCode); } /// /// Checks for an error in and calls /// and throws an exception if it's not valid /// /// The return code of the SDK call /// The number of references for the pointer that was used for the SDK call public static int CheckError(int countOrError) { if (countOrError == unchecked((int)0xFFFFFFFF)) throw new SDKException(ErrorCode.INVALID_HANDLE); else return countOrError; } /// /// Checks for an error in and calls /// and throws an exception if it's not valid /// /// The calling object instance. This is currently not used and is ignored. /// The return code of the SDK call /// The number of references for the pointer that was used for the SDK call public static int CheckError(object sender, int countOrError) { return CheckError(countOrError); } /// /// Reports an error that happened in a threading environment /// /// The sender object /// The exception that happened /// True if the error could be passed on; false otherwise public static bool ReportError(object sender, Exception ex) { var SevereErrorHappenedEvent = SevereErrorHappened; if (SevereErrorHappenedEvent == null) return false; else { SevereErrorHappenedEvent.BeginInvoke(sender, ex, (a) => { var ar = a as AsyncResult; var invokedMethod = ar.AsyncDelegate as GeneralExceptionHandler; invokedMethod.EndInvoke(a); }, null); return true; } } } }