// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. namespace System.Data.Entity { using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Runtime.Serialization.Formatters.Binary; using System.Threading; /// /// Common exception utilities. /// public static class ExceptionHelpers { /// /// Gets the error message thrown for types which implement IEnumerable only for cleaner construction. /// public static string EnumerableNotImplementedExceptionMessage { get { return "IEnumerable is only implemented for cleaner construction."; } } /// /// Throws ArgumentNullException if specified argument is null. /// /// Argument to check for null. /// Argument name. public static void CheckArgumentNotNull(object argument, string argumentName) { if (argument == null) { throw new ArgumentNullException(argumentName); } } /// /// Throws ArgumentException if the range is invalid. /// /// The type of the value. Must be comparable. /// The left value. /// Name of the left parameter. /// The right value. /// Name of the right parameter. public static void CheckValidRange(TValue leftValue, string leftParameterName, TValue rightValue, string rightParameterName) where TValue : struct, IComparable { if (leftValue.CompareTo(rightValue) > 0) { throw new ArgumentException( String.Format( CultureInfo.InvariantCulture, "Invalid range specified - '{0}' must be greater than or equal to '{1}'.", rightParameterName, leftParameterName)); } } /// /// Throws ArgumentException if string argument is empty and ArgumentNullException if string argument is null. /// /// String argument for check. /// Argument name. public static void CheckStringArgumentIsNotNullOrEmpty(string argument, string argumentName) { CheckArgumentNotNull(argument, argumentName); if (String.IsNullOrEmpty(argument)) { var message = String.Format(CultureInfo.InvariantCulture, "Argument '{0}' cannot be empty.", argumentName); throw new ArgumentException(message); } } /// /// Throws InvalidOperationException if specified string is null or empty /// /// The string to check for null/empty /// The exception message. /// The format arguments (if any) for the exception message. public static void CheckStringNotNullOrEmpty(string value, string exceptionMessageFormatText, params object[] messageArguments) { Assert(exceptionMessageFormatText != null, "message cannnot be null"); Assert(messageArguments != null, "messageArguments cannnot be null"); if (String.IsNullOrEmpty(value)) { throw new InvalidOperationException( String.Format(CultureInfo.InvariantCulture, exceptionMessageFormatText, messageArguments)); } } /// /// Throws InvalidOperationException if specified object is null. /// /// The object to check for null. /// The exception message. /// The format arguments (if any) for the exception message. public static void CheckObjectNotNull(object value, string exceptionMessageFormatText, params object[] messageArguments) { Assert(exceptionMessageFormatText != null, "message cannnot be null"); Assert(messageArguments != null, "messageArguments cannnot be null"); if (value == null) { var message = exceptionMessageFormatText; if (messageArguments.Length > 0) { message = String.Format(CultureInfo.InvariantCulture, exceptionMessageFormatText, messageArguments); } throw new InvalidOperationException(message); } } /// /// Throws ArgumentException if the given collection is null or empty. /// /// Type of the element type. /// The argument. /// Name of the argument. public static void CheckCollectionNotEmpty(IEnumerable argument, string argumentName) { CheckArgumentNotNull(argument, argumentName); if (!argument.Any()) { throw new ArgumentException( String.Format(CultureInfo.InvariantCulture, "Collection argument '{0}' must have at least one element.", argumentName)); } } /// /// Throws ArgumentException if the given collection is null or contains null elements. /// /// Type of the element type. /// The argument. /// Name of the argument. public static void CheckCollectionDoesNotContainNulls(IEnumerable argument, string argumentName) { CheckArgumentNotNull(argument, argumentName); if (argument.Any(e => e == null)) { throw new ArgumentException( String.Format(CultureInfo.InvariantCulture, "Collection argument '{0}' cannot contain null elements.", argumentName)); } } /// /// Throws NotSupportedException saying that IEnumerable is only implemented for cleaner construction. /// /// NotSupportedException with appropriate message public static NotSupportedException CreateIEnumerableNotImplementedException() { return new NotSupportedException(EnumerableNotImplementedExceptionMessage); } /// /// Determines whether the specified exception is catchable. /// /// The exception. /// A value true if the specified exception is catchable; otherwise, false . public static bool IsCatchable(Exception exception) { if (exception is ThreadAbortException) { return false; } return true; } /// /// Executes the given delegate and returns the exception that it throws. /// public static Exception GenerateException(Action willThrow) { try { willThrow(); } catch (Exception ex) { return ex; } Debug.Fail("Expected willThrow delegate to throw."); return null; } /// /// Serializes and de-serializes the given exception and returns the de-serialized instance. /// public static TException SerializeAndDeserialize(TException exception) where TException : Exception { var stream = new MemoryStream(); var formatter = new BinaryFormatter(); formatter.Serialize(stream, exception); stream.Seek(0, SeekOrigin.Begin); return (TException)formatter.Deserialize(stream); } /// /// Asserts the specified condition to be true and throws exception if it is not. /// /// If set to true , the exception will not be thrown. /// The error message. /// Arguments for the error message. public static void Assert(bool condition, string errorMessage, params object[] messageArguments) { if (!condition) { throw new InvalidOperationException( "ASSERTION FAILED: " + String.Format(CultureInfo.InvariantCulture, errorMessage, messageArguments)); } } public static void UnwrapAggregateExceptions(Action executor) { UnwrapAggregateExceptions( () => { executor(); return null; }); } /// /// Examines the AggregateExceptions thrown by the /// and rethrows the inner exception if only one is contained. /// public static T UnwrapAggregateExceptions(Func executor) { T result; try { result = executor(); } catch (AggregateException ae) { if (ae.InnerExceptions.Count == 1) { throw ae.InnerExceptions.Single(); } else { throw; } } return result; } } }