//----------------------------------------------------------------------- // // Copyright (c) Outercurve Foundation. All rights reserved. // //----------------------------------------------------------------------- namespace DotNetOpenAuth.Messaging { using System; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.Contracts; using System.Globalization; using System.Web; using DotNetOpenAuth.Logging; using Validation; /// /// A collection of error checking and reporting methods. /// [Pure] internal static class ErrorUtilities { /// /// Wraps an exception in a new . /// /// The inner exception to wrap. /// The error message for the outer exception. /// The string formatting arguments, if any. /// The newly constructed (unthrown) exception. [Pure] internal static Exception Wrap(Exception inner, string errorMessage, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(errorMessage != null); return new ProtocolException(string.Format(CultureInfo.CurrentCulture, errorMessage, args), inner); } /// /// Throws an internal error exception. /// /// The error message. /// Nothing. But included here so callers can "throw" this method for C# safety. /// Always thrown. [Pure] internal static Exception ThrowInternal(string errorMessage) { // Since internal errors are really bad, take this chance to // help the developer find the cause by breaking into the // debugger if one is attached. if (Debugger.IsAttached) { Debugger.Break(); } throw new InternalErrorException(errorMessage); } /// /// Checks a condition and throws an internal error exception if it evaluates to false. /// /// The condition to check. /// The message to include in the exception, if created. /// Thrown if evaluates to false. [Pure] internal static void VerifyInternal(bool condition, string errorMessage) { if (!condition) { ThrowInternal(errorMessage); } } /// /// Checks a condition and throws an internal error exception if it evaluates to false. /// /// The condition to check. /// The message to include in the exception, if created. /// The formatting arguments. /// Thrown if evaluates to false. [Pure] internal static void VerifyInternal(bool condition, string errorMessage, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(errorMessage != null); if (!condition) { errorMessage = string.Format(CultureInfo.CurrentCulture, errorMessage, args); throw new InternalErrorException(errorMessage); } } /// /// Checks a condition and throws an if it evaluates to false. /// /// The condition to check. /// The message to include in the exception, if created. /// Thrown if evaluates to false. [Pure] internal static void VerifyOperation(bool condition, string errorMessage) { if (!condition) { throw new InvalidOperationException(errorMessage); } } /// /// Checks a condition and throws a if it evaluates to false. /// /// The condition to check. /// The message to include in the exception, if created. /// Thrown if evaluates to false. [Pure] internal static void VerifySupported(bool condition, string errorMessage) { if (!condition) { throw new NotSupportedException(errorMessage); } } /// /// Checks a condition and throws a if it evaluates to false. /// /// The condition to check. /// The message to include in the exception, if created. /// The string formatting arguments for . /// Thrown if evaluates to false. [Pure] internal static void VerifySupported(bool condition, string errorMessage, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(errorMessage != null); if (!condition) { throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, errorMessage, args)); } } /// /// Checks a condition and throws an if it evaluates to false. /// /// The condition to check. /// The message to include in the exception, if created. /// The formatting arguments. /// Thrown if evaluates to false. [Pure] internal static void VerifyOperation(bool condition, string errorMessage, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(errorMessage != null); if (!condition) { errorMessage = string.Format(CultureInfo.CurrentCulture, errorMessage, args); throw new InvalidOperationException(errorMessage); } } /// /// Throws a if some evaluates to false. /// /// True to do nothing; false to throw the exception. /// The error message for the exception. /// The string formatting arguments, if any. /// Thrown if evaluates to false. [Pure] internal static void VerifyHost(bool condition, string errorMessage, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(errorMessage != null); if (!condition) { throw new HostErrorException(string.Format(CultureInfo.CurrentCulture, errorMessage, args)); } } /// /// Throws a if some evaluates to false. /// /// True to do nothing; false to throw the exception. /// The message being processed that would be responsible for the exception if thrown. /// The error message for the exception. /// The string formatting arguments, if any. /// Thrown if evaluates to false. [Pure] internal static void VerifyProtocol(bool condition, IProtocolMessage faultedMessage, string errorMessage, params object[] args) { Requires.NotNull(args, "args"); Requires.NotNull(faultedMessage, "faultedMessage"); Assumes.True(errorMessage != null); if (!condition) { throw new ProtocolException(string.Format(CultureInfo.CurrentCulture, errorMessage, args), faultedMessage); } } /// /// Throws a if some evaluates to false. /// /// True to do nothing; false to throw the exception. /// The error message for the exception. /// The string formatting arguments, if any. /// Thrown if evaluates to false. [Pure] internal static void VerifyProtocol(bool condition, string unformattedMessage, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(unformattedMessage != null); if (!condition) { var exception = new ProtocolException(string.Format(CultureInfo.CurrentCulture, unformattedMessage, args)); if (Logger.Messaging.IsErrorEnabled()) { Logger.Messaging.Error( string.Format( CultureInfo.CurrentCulture, "Protocol error: {0}{1}{2}", exception.Message, Environment.NewLine, new StackTrace())); } throw exception; } } /// /// Throws a . /// /// The message to set in the exception. /// The formatting arguments of the message. /// /// An InternalErrorException, which may be "thrown" by the caller in order /// to satisfy C# rules to show that code will never be reached, but no value /// actually is ever returned because this method guarantees to throw. /// /// Always thrown. [Pure] internal static Exception ThrowProtocol(string unformattedMessage, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(unformattedMessage != null); VerifyProtocol(false, unformattedMessage, args); // we never reach here, but this allows callers to "throw" this method. return new InternalErrorException(); } /// /// Throws a . /// /// The message for the exception. /// The string formatting arguments for . /// Nothing. It's just here so the caller can throw this method for C# compilation check. [Pure] internal static Exception ThrowFormat(string message, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(message != null); throw new FormatException(string.Format(CultureInfo.CurrentCulture, message, args)); } /// /// Throws a if some condition is false. /// /// The expression to evaluate. A value of false will cause the exception to be thrown. /// The message for the exception. /// The string formatting arguments for . /// Thrown when is false. [Pure] internal static void VerifyFormat(bool condition, string message, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(message != null); if (!condition) { throw ThrowFormat(message, args); } } /// /// Verifies something about the argument supplied to a method. /// /// The condition that must evaluate to true to avoid an exception. /// The message to use in the exception if the condition is false. /// The string formatting arguments, if any. /// Thrown if evaluates to false. [Pure] internal static void VerifyArgument(bool condition, string message, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(message != null); if (!condition) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, message, args)); } } /// /// Throws an . /// /// Name of the parameter. /// The message to use in the exception if the condition is false. /// The string formatting arguments, if any. /// Never returns anything. It always throws. [Pure] internal static Exception ThrowArgumentNamed(string parameterName, string message, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(message != null); throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, message, args), parameterName); } /// /// Verifies something about the argument supplied to a method. /// /// The condition that must evaluate to true to avoid an exception. /// Name of the parameter. /// The message to use in the exception if the condition is false. /// The string formatting arguments, if any. /// Thrown if evaluates to false. [Pure] internal static void VerifyArgumentNamed(bool condition, string parameterName, string message, params object[] args) { Requires.NotNull(args, "args"); Assumes.True(message != null); if (!condition) { throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, message, args), parameterName); } } /// /// Verifies that some given value is not null. /// /// The value to check. /// Name of the parameter, which will be used in the , if thrown. /// Thrown if is null. [Pure] internal static void VerifyArgumentNotNull(object value, string paramName) { if (value == null) { throw new ArgumentNullException(paramName); } } /// /// Verifies that some string is not null and has non-zero length. /// /// The value to check. /// Name of the parameter, which will be used in the , if thrown. /// Thrown if is null. /// Thrown if has zero length. [Pure] internal static void VerifyNonZeroLength(string value, string paramName) { VerifyArgumentNotNull(value, paramName); if (value.Length == 0) { throw new ArgumentException(MessagingStrings.UnexpectedEmptyString, paramName); } } /// /// Verifies that != null. /// /// Thrown if == null [Pure] internal static void VerifyHttpContext() { ErrorUtilities.VerifyOperation(HttpContext.Current != null && HttpContext.Current.Request != null, MessagingStrings.HttpContextRequired); } /// /// Obtains a value from the dictionary if possible, or throws a if it's missing. /// /// The type of key in the dictionary. /// The type of value in the dictionary. /// The dictionary. /// The key to use to look up the value. /// The message to claim is invalid if the key cannot be found. /// The value for the given key. [Pure] internal static TValue GetValueOrThrow(this IDictionary dictionary, TKey key, IMessage message) { Requires.NotNull(dictionary, "dictionary"); Requires.NotNull(message, "message"); TValue value; VerifyProtocol(dictionary.TryGetValue(key, out value), MessagingStrings.ExpectedParameterWasMissing, key, message.GetType().Name); return value; } } }