Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

257 lines
10 KiB
C#

// 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;
/// <summary>
/// Common exception utilities.
/// </summary>
public static class ExceptionHelpers
{
/// <summary>
/// Gets the error message thrown for types which implement IEnumerable only for cleaner construction.
/// </summary>
public static string EnumerableNotImplementedExceptionMessage
{
get { return "IEnumerable is only implemented for cleaner construction."; }
}
/// <summary>
/// Throws ArgumentNullException if specified argument is null.
/// </summary>
/// <param name="argument"> Argument to check for null. </param>
/// <param name="argumentName"> Argument name. </param>
public static void CheckArgumentNotNull(object argument, string argumentName)
{
if (argument == null)
{
throw new ArgumentNullException(argumentName);
}
}
/// <summary>
/// Throws ArgumentException if the range is invalid.
/// </summary>
/// <typeparam name="TValue"> The type of the value. Must be comparable. </typeparam>
/// <param name="leftValue"> The left value. </param>
/// <param name="leftParameterName"> Name of the left parameter. </param>
/// <param name="rightValue"> The right value. </param>
/// <param name="rightParameterName"> Name of the right parameter. </param>
public static void CheckValidRange<TValue>(TValue leftValue, string leftParameterName, TValue rightValue, string rightParameterName)
where TValue : struct, IComparable<TValue>
{
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));
}
}
/// <summary>
/// Throws ArgumentException if string argument is empty and ArgumentNullException if string argument is null.
/// </summary>
/// <param name="argument"> String argument for check. </param>
/// <param name="argumentName"> Argument name. </param>
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);
}
}
/// <summary>
/// Throws InvalidOperationException if specified string is null or empty
/// </summary>
/// <param name="value"> The string to check for null/empty </param>
/// <param name="exceptionMessageFormatText"> The exception message. </param>
/// <param name="messageArguments"> The format arguments (if any) for the exception message. </param>
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));
}
}
/// <summary>
/// Throws InvalidOperationException if specified object is null.
/// </summary>
/// <param name="value"> The object to check for null. </param>
/// <param name="exceptionMessageFormatText"> The exception message. </param>
/// <param name="messageArguments"> The format arguments (if any) for the exception message. </param>
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);
}
}
/// <summary>
/// Throws ArgumentException if the given collection is null or empty.
/// </summary>
/// <typeparam name="TElement"> Type of the element type. </typeparam>
/// <param name="argument"> The argument. </param>
/// <param name="argumentName"> Name of the argument. </param>
public static void CheckCollectionNotEmpty<TElement>(IEnumerable<TElement> 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));
}
}
/// <summary>
/// Throws ArgumentException if the given collection is null or contains null elements.
/// </summary>
/// <typeparam name="TElement"> Type of the element type. </typeparam>
/// <param name="argument"> The argument. </param>
/// <param name="argumentName"> Name of the argument. </param>
public static void CheckCollectionDoesNotContainNulls<TElement>(IEnumerable<TElement> 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));
}
}
/// <summary>
/// Throws NotSupportedException saying that IEnumerable is only implemented for cleaner construction.
/// </summary>
/// <returns> NotSupportedException with appropriate message </returns>
public static NotSupportedException CreateIEnumerableNotImplementedException()
{
return new NotSupportedException(EnumerableNotImplementedExceptionMessage);
}
/// <summary>
/// Determines whether the specified exception is catchable.
/// </summary>
/// <param name="exception"> The exception. </param>
/// <returns> A value <c>true</c> if the specified exception is catchable; otherwise, <c>false</c> . </returns>
public static bool IsCatchable(Exception exception)
{
if (exception is ThreadAbortException)
{
return false;
}
return true;
}
/// <summary>
/// Executes the given delegate and returns the exception that it throws.
/// </summary>
public static Exception GenerateException(Action willThrow)
{
try
{
willThrow();
}
catch (Exception ex)
{
return ex;
}
Debug.Fail("Expected willThrow delegate to throw.");
return null;
}
/// <summary>
/// Serializes and de-serializes the given exception and returns the de-serialized instance.
/// </summary>
public static TException SerializeAndDeserialize<TException>(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);
}
/// <summary>
/// Asserts the specified condition to be true and throws exception if it is not.
/// </summary>
/// <param name="condition"> If set to <c>true</c> , the exception will not be thrown. </param>
/// <param name="errorMessage"> The error message. </param>
/// <param name="messageArguments"> Arguments for the error message. </param>
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<object>(
() =>
{
executor();
return null;
});
}
/// <summary>
/// Examines the AggregateExceptions thrown by the <paramref name="executor" />
/// and rethrows the inner exception if only one is contained.
/// </summary>
public static T UnwrapAggregateExceptions<T>(Func<T> executor)
{
T result;
try
{
result = executor();
}
catch (AggregateException ae)
{
if (ae.InnerExceptions.Count == 1)
{
throw ae.InnerExceptions.Single();
}
else
{
throw;
}
}
return result;
}
}
}