/******************************************************************************* Copyright (c) 2010, Perforce Software, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PERFORCE SOFTWARE, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *******************************************************************************/ /******************************************************************************* * Name : P4Exception.cs * * Author : dbb * * Description : Classes used to provide typed exception handling. * ******************************************************************************/ using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Perforce.P4 { /// /// Base class for exceptions caused by run time errors from the server. /// They can be disabled, by setting the MinThrowLevel to /// ErrorSeverity.E_NOEXC. /// public class P4Exception : Exception { static ErrorSeverity minLevel = ErrorSeverity.E_FAILED; private P4Exception nextError; private ErrorSeverity errorLevel; private int errorCode; private string message; private P4ClientInfoMessageList details; private string cmdLine; /// /// If more than one error was returned by a command, the next /// error in the list. /// public P4Exception NextError { get { return nextError; } } /// /// Severity of the error /// public ErrorSeverity ErrorLevel { get { return errorLevel; } } /// /// Error number from the C++ API /// public int ErrorCode { get { return errorCode; } } /// /// Error message /// public override string Message { get { return message; } } /// /// Error message /// public P4ClientInfoMessageList Details { get { return details; } } /// /// Error message /// public string CmdLine { get { return cmdLine; } } /// /// Create a new P4Exception /// /// Severity level /// Error message public P4Exception(ErrorSeverity nLevel, String nMessage) { errorCode = 0; errorLevel = nLevel; message = nMessage; nextError = null; } /// /// Create a new P4Exception /// /// Severity level /// Error message /// Next error in sequence public P4Exception(ErrorSeverity nLevel, String nMessage, P4Exception NextError) { errorCode = 0; errorLevel = nLevel; message = nMessage; nextError = NextError; } /// /// Create a new P4Exception /// /// command which was run /// arguments to the command /// Severity level /// Error message public P4Exception(string cmd, string[] args, ErrorSeverity nLevel, String nMessage) { errorCode = 0; errorLevel = nLevel; message = nMessage; nextError = null; cmdLine = cmd; if (args != null) { for (int idx = 0; idx < args.Length; idx++) { if (string.IsNullOrEmpty(args[idx]) == false) { cmdLine += " " + args[idx]; } } } } /// /// Create a new P4Exception /// /// Client error causing the exception public P4Exception(P4ClientError error) { errorCode = error.ErrorCode; errorLevel = error.SeverityLevel; message = error.ErrorMessage; nextError = null; } /// /// Create a new P4Exception /// /// command which was run /// arguments passed to the command /// Client error causing the exception public P4Exception(string cmd, string[] args, P4ClientError error) { errorCode = error.ErrorCode; errorLevel = error.SeverityLevel; message = error.ErrorMessage; nextError = null; cmdLine = cmd; if (args != null) { for (int idx = 0; idx < args.Length; idx++) { if (string.IsNullOrEmpty(args[idx]) == false) { cmdLine += " " + args[idx]; } } } } /// /// Create a list of new P4Exceptions /// /// The list of errors which caused the exception public P4Exception(P4ClientErrorList errors) { if (errors.Count < 1) return; errorLevel = errors[0].SeverityLevel; errorCode = errors[0].ErrorCode; message = errors[0].ErrorMessage; P4Exception currentException = this; for (int idx = 1; idx < errors.Count; idx++) { currentException.nextError = new P4Exception(errors[idx]); currentException = currentException.nextError; } } /// /// Create a list of new P4Exceptions /// /// command which was run /// arguments to the command /// The list of errors which caused the exception public P4Exception(string cmd, string[] args, P4ClientErrorList errors) { if (errors.Count < 1) return; cmdLine = cmd; if (args != null) { for (int idx = 0; idx < args.Length; idx++) { if (string.IsNullOrEmpty(args[idx]) == false) { cmdLine += " " + args[idx]; } } } errorLevel = errors[0].SeverityLevel; errorCode = errors[0].ErrorCode; message = errors[0].ErrorMessage; P4Exception currentException = this; for (int idx = 1; idx < errors.Count; idx++) { currentException.nextError = new P4Exception(errors[idx]); currentException = currentException.nextError; } } /// /// Create a list of new P4Exceptions /// /// The list of errors which caused the exception /// The info output of the command which caused the exception internal P4Exception(P4ClientErrorList errors, P4ClientInfoMessageList nDetails) { if (errors.Count < 1) return; errorLevel = errors[0].SeverityLevel; errorCode = errors[0].ErrorCode; message = errors[0].ErrorMessage; P4Exception currentException = this; for (int idx = 1; idx < errors.Count; idx++) { currentException.nextError = new P4Exception(errors[idx]); currentException = currentException.nextError; } details = nDetails; } /// /// Create a list of new P4Exceptions /// /// command which was run /// arguments to the command /// The list of errors which caused the exception /// The info output of the command which caused the exception internal P4Exception(string cmd, string[] args, P4ClientErrorList errors, P4ClientInfoMessageList nDetails) { if (errors.Count < 1) return; cmdLine = cmd; if (args != null) { for (int idx = 0; idx < args.Length; idx++) { if (string.IsNullOrEmpty(args[idx]) == false) { cmdLine += " " + args[idx]; } } } errorLevel = errors[0].SeverityLevel; errorCode = errors[0].ErrorCode; message = errors[0].ErrorMessage; P4Exception currentException = this; for (int idx = 1; idx < errors.Count; idx++) { currentException.nextError = new P4Exception(errors[idx]); currentException = currentException.nextError; } details = nDetails; } /// /// Minimum error to cause an exception to be thrown /// public static ErrorSeverity MinThrowLevel { get { return minLevel; } set { minLevel = value; } } /// /// Create and throw an exception if it exceeds the MinThrowLevel /// /// Severity level /// Error message public static void Throw(ErrorSeverity nLevel, String nMessage) { if (nLevel >= minLevel) throw new P4Exception(nLevel, nMessage); } /// /// Create and throw an exception if it exceeds the MinThrowLevel /// /// command which was run /// arguments to the command /// Severity level /// Error message public static void Throw(string cmd, string[] args, ErrorSeverity nLevel, String nMessage) { if (nLevel >= minLevel) throw new P4Exception(cmd, args, nLevel, nMessage); } /// /// Create and throw an exception if it exceeds the MinThrowLevel /// /// Client error causing the exception public static void Throw(P4ClientError error) { if (error.SeverityLevel >= minLevel) throw new P4Exception(error); } /// /// Create and throw an exception if it exceeds the MinThrowLevel /// /// command which was run /// arguments to the command /// Client error causing the exception public static void Throw(string cmd, string[] args, P4ClientError error) { if (error.SeverityLevel >= minLevel) throw new P4Exception(cmd, args, error); } /// /// Throw if any error in the list exceeds minLevel /// /// List of client errors causing the exception internal static void Throw(P4ClientErrorList errors) { foreach (P4ClientError current in errors) { if (current.SeverityLevel >= minLevel) throw new P4Exception(errors); } } /// /// Throw if any error in the list exceeds minLevel /// /// command which was run /// arguments to the command /// List of client errors causing the exception internal static void Throw(string cmd, string[] args, P4ClientErrorList errors) { foreach (P4ClientError current in errors) { if (current.SeverityLevel >= minLevel) throw new P4Exception(cmd, args, errors); } } /// /// Throw if any error in the list exceeds minLevel /// /// List of client errors causing the exception /// P4ClientInfoMessageList details internal static void Throw(P4ClientErrorList errors, P4ClientInfoMessageList details) { foreach (P4ClientError current in errors) { if (current.SeverityLevel >= minLevel) throw new P4Exception(errors, details); } } /// /// Throw if any error in the list exceeds minLevel /// /// /// /// List of client errors causing the exception /// P4ClientInfoMessageList details internal static void Throw(string cmd, string[] args, P4ClientErrorList errors, P4ClientInfoMessageList details) { foreach (P4ClientError current in errors) { if (current.SeverityLevel >= minLevel) throw new P4Exception(cmd, args, errors, details); } } } /// /// Specialized Exception for lost connection /// public class P4LostConnectionException : P4Exception { /// /// Construct a P4LostConnectionException /// /// severity level /// exception message public P4LostConnectionException(ErrorSeverity nLevel, String nMessage) : base(nLevel, nMessage) { } } /// /// Specialized Exception for command time out /// public class P4CommandTimeOutException : P4Exception { /// /// Construct a P4CommandTimeOutException /// /// severity level /// exception message public P4CommandTimeOutException(ErrorSeverity nLevel, String nMessage) : base(nLevel, nMessage) { } } /// /// Specialized Exception for canceled command /// public class P4CommandCanceledException : P4Exception { /// /// Construct a P4CommandCanceled Exception /// /// exception message public P4CommandCanceledException(String nMessage) : base(ErrorSeverity.E_FATAL, nMessage) { } } /// /// Specialized Exception for Hung command /// public class P4HungCommandCancelException : P4Exception { /// /// Construct a P4HungCommandCanceled Exception /// /// exception message public P4HungCommandCancelException(String nMessage) : base(ErrorSeverity.E_FATAL, nMessage) { } } /// /// Specialized Exception for Can't close exception /// public class P4CantCloseConnectionException : P4Exception { /// /// Construct a P4CantCloseConnectionException /// public P4CantCloseConnectionException() : base(ErrorSeverity.E_FAILED, "Can't close conection, the server is still running commands") { } } /// /// Specialized Exception to handle Trust failures /// public class P4TrustException : P4Exception { /// /// Create a P4TrustException /// public P4TrustException() : base(ErrorSeverity.E_FATAL, "Trust Issue") { } /// /// Create a P4TrustException /// /// severity level /// exception message public P4TrustException(ErrorSeverity nLevel, String nMessage) : base(nLevel, nMessage) { } } }