blob: 912493da4d2b8bf6dee6d34092857cdf87e883fd [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
using System;
using System.Runtime.ExceptionServices;
using System.Text;
using Org.Apache.REEF.Utilities.Logging;
using Org.Apache.REEF.Utilities.Attributes;
namespace Org.Apache.REEF.Utilities.Diagnostics
{
[Private]
public static class Exceptions
{
#region methods
/// <summary>
/// Call this method to throw an exception.
/// </summary>
/// <remarks>
/// Calling this method will trace the exception and do other common processing,
/// and then it will throw the exception. This method traces the exception type
/// and message at error level and the full stack trace at all other levels.
/// </remarks>
/// <example>
/// Exceptions.Throw(new Exception("Some exception"));
/// </example>
/// <param name="exception">The exception to be thrown.</param>
/// <param name="message">The message from the caller class.</param>
/// <param name="logger">The logger from the caller class.</param>
public static void Throw(Exception exception, string message, Logger logger)
{
string logMessage = string.Concat(DiagnosticsMessages.ExceptionThrowing, " ", exception.GetType().Name, " ", message);
if (logger == null)
{
Console.WriteLine("Exception caught before logger is initiated, error message: " + logMessage + exception.Message);
}
else
{
logger.Log(Level.Error, logMessage, exception);
}
ExceptionDispatchInfo.Capture(exception).Throw();
}
/// <summary>
/// Call this method to throw an exception.
/// </summary>
/// <remarks>
/// Calling this method will trace the exception and do other common processing,
/// and then it will throw the exception. This method traces the exception type
/// and message at error level and the full stack trace at all other levels.
/// </remarks>
/// <example>
/// Exceptions.Throw(new Exception("Some exception"));
/// </example>
/// <param name="exception">The exception to be thrown.</param>
/// <param name="logger">The logger of the caller class.</param>
public static void Throw(Exception exception, Logger logger)
{
Throw(exception, string.Empty, logger);
}
/// <summary>
/// Call this method every time when an exception is caught.
/// </summary>
/// <remarks>
/// Calling this method will trace the exception and do other common processing.
/// This method traces the exception type and message at error level and the full
/// stack trace at all other levels.
/// </remarks>
/// <example>
/// try
/// {
/// // Some code that can throw
/// }
/// catch (Exception e)
/// {
/// Exceptions.Caught(e);
/// // Exception handling code
/// }
/// </example>
/// <param name="exception">The exception being caught.</param>
/// <param name="level">The log level.</param>
/// <param name="logger">The logger from the caller class.</param>
public static void Caught(Exception exception, Level level, Logger logger)
{
Caught(exception, level, string.Empty, logger);
}
/// <summary>
/// Call this method every time when an exception is caught.
/// </summary>
/// <remarks>
/// Calling this method will trace the exception and do other common processing.
/// This method traces the exception type and message at error level and the full
/// stack trace at all other levels.
/// </remarks>
/// <example>
/// try
/// {
/// // Some code that can throw
/// }
/// catch (Exception e)
/// {
/// Exceptions.Caught(e);
/// // Exception handling code
/// }
/// </example>
/// <param name="exception">The exception being caught.</param>
/// <param name="level">The log level.</param>
/// <param name="message">The additional message to log.</param>
/// <param name="logger">The Logger from the caller class.</param>
public static void Caught(Exception exception, Level level, string message, Logger logger)
{
string logMessage = string.Concat(DiagnosticsMessages.ExceptionCaught, " ", exception.GetType().Name, " ", message);
if (logger == null)
{
Console.WriteLine("Exception caught before logger is initiated, error message: " + logMessage + exception.Message);
}
else
{
logger.Log(level, logMessage, exception);
}
}
public static void CaughtAndThrow(Exception exception, Level level, Logger logger)
{
CaughtAndThrow(exception, level, string.Empty, logger);
}
public static void CaughtAndThrow(Exception exception, Level level, string message, Logger logger)
{
string logMessage = string.Concat(DiagnosticsMessages.ExceptionCaught, " ", exception.GetType().Name, " ", message);
if (logger == null)
{
Console.WriteLine("Exception caught before logger is initiated, error message: " + logMessage + exception.Message);
}
else
{
logger.Log(level, logMessage, exception);
}
ExceptionDispatchInfo.Capture(exception).Throw();
}
/// <summary>
/// This method returns true if the exception passed as parameter is a critical exception
/// that should have not been caught. Examples for such exceptions are StackOverflowException
/// and OutOfMemoryException.
/// </summary>
/// <remarks>
/// Catch statements which catch all exceptions must call this method immediately and rethrow
/// without further processing if the method returns true.
/// </remarks>
/// <example>
/// try
/// {
/// // Some code that can throw
/// }
/// catch (Exception e)
/// {
/// if (Exceptions.MustRethrow(e))
/// {
/// throw;
/// }
/// // Exception handling code
/// }
/// </example>
/// <param name="exception">The exception to be checked.</param>
/// <returns>True if the exceptions is critical one and should not be caught and false otherwise.</returns>
public static bool MustRethrow(Exception exception)
{
return exception is OutOfMemoryException ||
exception is StackOverflowException;
}
/// <summary>
/// Gets an exception message that includes the messages of the inner exceptions.
/// </summary>
/// <param name="e">The exception.</param>
/// <returns>The message</returns>
public static string GetFullMessage(Exception e)
{
var fullMessage = new StringBuilder();
bool firstLevel = true;
while (e != null)
{
if (firstLevel)
{
firstLevel = false;
}
else
{
fullMessage.Append("-->");
}
fullMessage.Append(e.Message);
e = e.InnerException;
}
return fullMessage.ToString();
}
/// <summary>
/// Call this method to throw ArgumentException for an invalid argument.
/// </summary>
/// <param name="argumentName">The invalid argument name.</param>
/// <param name="message">A message explaining the reason for th exception.</param>
/// <param name="logger">The logger of the caller class.</param>
public static void ThrowInvalidArgument(string argumentName, string message, Logger logger)
{
Throw(new ArgumentException(message, argumentName), logger);
}
/// <summary>
/// Call this method to throw ArgumentOutOfRangeException exception.
/// </summary>
/// <param name="argumentName">The invalid argument name.</param>
/// <param name="message">A message explaining the reason for th exception.</param>
/// <param name="logger">The logger of the caller class.</param>
public static void ThrowArgumentOutOfRange(string argumentName, string message, Logger logger)
{
Throw(new ArgumentOutOfRangeException(argumentName, message), logger);
}
/// <summary>
/// Call this method to check if an argument is null and throw ArgumentNullException exception.
/// </summary>
/// <param name="argument">The argument to be checked.</param>
/// <param name="name">The name of the argument.</param>
/// <param name="logger">The logger of the caller class.</param>
public static void ThrowIfArgumentNull(object argument, string name, Logger logger)
{
if (argument == null)
{
Exceptions.Throw(new ArgumentNullException(name), logger);
}
}
/// <summary>
/// Call this method to throw ObjectDisposedException if an object is disposed.
/// </summary>
/// <remarks>
/// All disposable objects should check their state and throw in the beginning of each public method.
/// This helper method provides a shorter way to do this.
/// </remarks>
/// <example>
/// class SomeClass : IDisposable
/// {
/// bool _disposed;
/// // ...
/// public void SomePublicMethod()
/// {
/// Exceptions.ThrowIfObjectDisposed(_disposed, this);
/// // Method's code
/// }
/// }
/// </example>
/// <param name="disposed">True if the object is disposed.</param>
/// <param name="o">The object.</param>
/// <param name="logger">The logger of the caller class.</param>
public static void ThrowIfObjectDisposed(bool disposed, object o, Logger logger)
{
if (disposed)
{
Throw(new ObjectDisposedException(o.GetType().Name), logger);
}
}
#endregion
}
}