ObjectManagerExceptionHelper
Defines a static helper method to inspect common Object Manager exceptions.
using Relativity.Services.Exceptions;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text.RegularExpressions;
namespace Relativity.DataExchange.Service
{
internal static class ObjectManagerExceptionHelper
{
public const int MaxInnerExceptionDepth = 16;
public static bool IsNonFatalError(Exception exception)
{
if (exception == null)
throw new ArgumentNullException("exception");
if (!IsInvalidParametersError(exception) && !IsServerSideFileNotFoundError(exception) && !IsServerSideFilePermissionsError(exception))
return IsServerSideDirectoryNotFoundError(exception);
return true;
}
public static bool IsInvalidParametersError(Exception exception)
{
if (exception == null)
return false;
if (!(exception is ValidationException))
return IsMatch(exception, "^Read Failed$");
return true;
}
public static bool IsServerSideDirectoryNotFoundError(Exception exception)
{
if (exception == null)
return false;
return TrySearchServiceExceptionErrorDetails(exception, (IDictionary<string, object> errorDetailsDictionary) => IsInnerExceptionClassName(errorDetailsDictionary, typeof(DirectoryNotFoundException)));
}
public static bool IsServerSideFileNotFoundError(Exception exception)
{
if (exception == null)
return false;
return TrySearchServiceExceptionErrorDetails(exception, (IDictionary<string, object> errorDetailsDictionary) => IsInnerExceptionClassName(errorDetailsDictionary, typeof(FileNotFoundException)));
}
public static bool IsServerSideFilePermissionsError(Exception exception)
{
if (exception == null)
return false;
return TrySearchServiceExceptionErrorDetails(exception, (IDictionary<string, object> errorDetailsDictionary) => IsInnerExceptionClassName(errorDetailsDictionary, typeof(UnauthorizedAccessException)));
}
private static bool IsMatch(Exception exception, string pattern)
{
if (string.IsNullOrWhiteSpace(exception.Message))
return false;
return Regex.IsMatch(exception.Message, pattern, RegexOptions.IgnoreCase);
}
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "By design, this method will never fail.")]
private static bool TrySearchServiceExceptionErrorDetails(Exception exception, Func<IDictionary<string, object>, bool> innerExceptionFunc)
{
try {
ServiceException val = exception as ServiceException;
if (val != null) {
IDictionary<string, object> dictionary = (IDictionary<string, object>)val.get_ErrorDetails();
int num = 0;
while (dictionary != null && num < 16) {
num++;
if (innerExceptionFunc(dictionary))
return true;
if (!dictionary.ContainsKey("InnerException"))
break;
dictionary = (dictionary["InnerException"] as IDictionary<string, object>);
}
return false;
}
return false;
} catch {
return false;
}
}
private static bool IsInnerExceptionClassName(IDictionary<string, object> errorDetailsDictionary, Type expectedType)
{
if (!errorDetailsDictionary.ContainsKey("ClassName"))
return false;
string stringValue = errorDetailsDictionary.GetStringValue("ClassName", string.Empty);
if (!string.IsNullOrWhiteSpace(stringValue))
return stringValue.IndexOf(expectedType.Name, StringComparison.OrdinalIgnoreCase) >= 0;
return false;
}
}
}