ExceptionHelper
Defines static helper methods to perform common exception handling.
using Relativity.DataExchange.Resources;
using Relativity.Kepler.Exceptions;
using Relativity.Services.Exceptions;
using Relativity.Services.Objects.Exceptions;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Services.Protocols;
namespace Relativity.DataExchange
{
internal static class ExceptionHelper
{
public const int DiskFullHResultHResult = -2147024784;
public const int HandleDiskFullHResult = -2147024857;
public const string IllegalCharactersInPathMessage = "Illegal characters in path.";
public const string TryAgainAdminFatalMessage = "Try again. If the problem persists please contact your system administrator for assistance.";
public const string BatchInProgressMessage = "Batch In Progress";
public static readonly IReadOnlyList<Type> FatalExceptionCandidates = new List<Type>(new Type[14] {
typeof(AccessViolationException),
typeof(ApplicationException),
typeof(BadImageFormatException),
typeof(DivideByZeroException),
typeof(DllNotFoundException),
typeof(EntryPointNotFoundException),
typeof(InsufficientMemoryException),
typeof(NullReferenceException),
typeof(OutOfMemoryException),
typeof(OverflowException),
typeof(SecurityException),
typeof(StackOverflowException),
typeof(ThreadAbortException),
typeof(FileNotFoundException)
});
public static readonly IReadOnlyList<Type> FatalKeplerExceptionCandidates = new List<Type>(new Type[4] {
typeof(NotAuthorizedException),
typeof(WireProtocolMismatchException),
typeof(NotFoundException),
typeof(PermissionDeniedException)
});
private static readonly string[] FatalKeplerExceptionMessagesFragments = new string[1] {
"InvalidAppArtifactID"
};
private static IEnumerable<HttpStatusCode> DefaultFatalHttpStatusCodes => new List<HttpStatusCode>(new HttpStatusCode[4] {
HttpStatusCode.BadRequest,
HttpStatusCode.NotFound,
HttpStatusCode.Forbidden,
HttpStatusCode.Unauthorized
});
private static IEnumerable<WebExceptionStatus> DefaultFatalWebExceptionStatusCodes => new List<WebExceptionStatus>(new WebExceptionStatus[1] {
WebExceptionStatus.TrustFailure
});
public static string AppendTryAgainAdminFatalMessage(string message)
{
if (!string.IsNullOrEmpty(message))
message = message.TrimEnd(' ', '.') + ". ";
return message + "Try again. If the problem persists please contact your system administrator for assistance.";
}
public static string GetDetailedFatalMessage(HttpStatusCode statusCode)
{
switch (statusCode) {
case HttpStatusCode.BadRequest:
return Strings.HttpBadRequestFatalMessage;
case HttpStatusCode.NotFound:
return Strings.HttpNotFoundFatalMessage;
case HttpStatusCode.Forbidden:
return Strings.HttpForbiddenFatalMessage;
case HttpStatusCode.Unauthorized:
return Strings.HttpUnauthorizedFatalMessage;
default:
return string.Empty;
}
}
public static string GetDetailedFatalMessage(WebExceptionStatus status)
{
if (status == WebExceptionStatus.TrustFailure)
return Strings.WebExceptionTrustFailureMessage;
return string.Empty;
}
public static bool IsEndpointNotFound(SoapException exception, string name)
{
return IsSoapEndpointNotFound((Exception)exception, name);
}
public static bool IsFatalException(Exception exception)
{
if (exception == null)
throw new ArgumentNullException("exception");
Type exceptionType = exception.GetType();
if (!FatalExceptionCandidates.Any((Type exceptionCandidateType) => exceptionCandidateType.IsAssignableFrom(exceptionType)) && !IsFatalWebException(exception) && !IsFatalServiceInfrastructureException(exception))
return IsOutOfDiskSpaceException(exception);
return true;
}
public static bool IsFatalKeplerException(Exception exception)
{
if (exception == null)
throw new ArgumentNullException("exception");
Type exceptionType = exception.GetType();
if (FatalKeplerExceptionCandidates.Any((Type exceptionCandidateType) => exceptionCandidateType.IsAssignableFrom(exceptionType)))
return true;
if (FatalKeplerExceptionMessagesFragments.Any((string fragment) => exception.Message.Contains(fragment)))
return true;
return false;
}
public static bool IsIllegalCharactersInPathException(Exception exception)
{
if (exception == null)
throw new ArgumentNullException("exception");
if (exception is ArgumentException)
return exception.Message.Contains("Illegal characters in path.");
return false;
}
public static bool IsOutOfDiskSpaceException(Exception exception)
{
if (exception == null)
throw new ArgumentNullException("exception");
if (!(exception is IOException))
return false;
if (exception.HResult != -2147024857)
return exception.HResult == -2147024784;
return true;
}
public static bool IsFatalWebException(Exception exception)
{
return IsFatalWebException(exception as WebException);
}
public static bool IsFatalWebException(WebException exception)
{
HttpStatusCode? nullable = (exception?.Response as HttpWebResponse)?.StatusCode;
if (nullable.HasValue)
return IsHttpStatusCodeFatalError(nullable.Value);
return false;
}
public static bool IsHttpStatusCodeFatalError(HttpStatusCode statusCode)
{
return DefaultFatalHttpStatusCodes.Any((HttpStatusCode x) => x == statusCode);
}
public static bool IsBatchInProgressException(Exception exception)
{
if (exception == null)
throw new ArgumentNullException("exception");
if (exception.GetType() == typeof(ConflictException))
return exception.Message.Contains("Batch In Progress");
return false;
}
public static bool IsSoapEndpointNotFound(Exception exception)
{
return IsSoapEndpointNotFound(exception, string.Empty);
}
public static bool IsSoapEndpointNotFound(Exception exception, string name)
{
if (string.IsNullOrWhiteSpace(exception.Message))
return false;
bool num = exception.Message.IndexOf("Server did not recognize the value of HTTP Header", StringComparison.CurrentCultureIgnoreCase) >= 0;
bool flag = string.IsNullOrEmpty(name) || exception.Message.IndexOf(name, StringComparison.CurrentCultureIgnoreCase) >= 0;
return num & flag;
}
public static bool IsSuspectedHttpTimeoutException(Exception exception)
{
AggregateException ex = exception as AggregateException;
if (ex == null || !(ex.InnerException is TaskCanceledException))
return false;
return !((TaskCanceledException)ex.InnerException).CancellationToken.IsCancellationRequested;
}
public static bool IsWebExceptionStatusCodeFatalError(WebExceptionStatus status)
{
return DefaultFatalWebExceptionStatusCodes.Any((WebExceptionStatus x) => x == status);
}
private static bool IsFatalServiceInfrastructureException(Exception exception)
{
return exception is ServiceNotFoundException;
}
}
}