namespace Unosquare.Swan.Exceptions
{
using System;
using Networking.Ldap;
///
/// Thrown to indicate that an Ldap exception has occurred. This is a general
/// exception which includes a message and an Ldap result code.
/// An LdapException can result from physical problems (such as
/// network errors) as well as problems with Ldap operations detected
/// by the server. For example, if an Ldap add operation fails because of a
/// duplicate entry, the server returns a result code.
///
///
public class LdapException
: Exception
{
internal const string UnexpectedEnd = "Unexpected end of filter";
internal const string MissingLeftParen = "Unmatched parentheses, left parenthesis missing";
internal const string MissingRightParen = "Unmatched parentheses, right parenthesis missing";
internal const string ExpectingRightParen = "Expecting right parenthesis, found \"{0}\"";
internal const string ExpectingLeftParen = "Expecting left parenthesis, found \"{0}\"";
private readonly string _serverMessage;
///
/// Initializes a new instance of the class.
/// Constructs an exception with a detailed message obtained from the
/// specified MessageOrKey String.
/// Additional parameters specify the result code, the message returned
/// from the server, and a matchedDN returned from the server.
/// The String is used either as a message key to obtain a localized
/// message from ExceptionMessages, or if there is no key in the
/// resource matching the text, it is used as the detailed message itself.
///
/// The message.
/// The result code returned.
/// Error message specifying additional information
/// from the server.
/// The maximal subset of a specified DN which could
/// be matched by the server on a search operation.
/// The root exception.
public LdapException(
string message,
LdapStatusCode resultCode,
string serverMsg = null,
string matchedDN = null,
Exception rootException = null)
: base(message)
{
ResultCode = resultCode;
Cause = rootException;
MatchedDN = matchedDN;
_serverMessage = serverMsg;
}
///
/// Returns the error message from the Ldap server, if this message is
/// available (that is, if this message was set). If the message was not set,
/// this method returns null.
///
///
/// The error message or null if the message was not set.
///
public string LdapErrorMessage =>
_serverMessage != null && _serverMessage.Length == 0 ? null : _serverMessage;
///
/// Returns the lower level Exception which caused the failure, if any.
/// For example, an IOException with additional information may be returned
/// on a CONNECT_ERROR failure.
///
///
/// The cause.
///
public Exception Cause { get; }
///
/// Returns the result code from the exception.
/// The codes are defined as public final static int members
/// of the Ldap Exception class. If the exception is a
/// result of error information returned from a directory operation, the
/// code will be one of those defined for the class. Otherwise, a local error
/// code is returned.
///
///
/// The result code.
///
public LdapStatusCode ResultCode { get; }
///
/// Returns the part of a submitted distinguished name which could be
/// matched by the server.
/// If the exception was caused by a local error, such as no server
/// available, the return value is null. If the exception resulted from
/// an operation being executed on a server, the value is an empty string
/// except when the result of the operation was one of the following:.
/// - NO_SUCH_OBJECT
- ALIAS_PROBLEM
- INVALID_DN_SYNTAX
- ALIAS_DEREFERENCING_PROBLEM
///
///
/// The matched dn.
///
public string MatchedDN { get; }
///
public override string Message => ResultCode.ToString().Humanize();
///
public override string ToString()
{
// Craft a string from the resource file
var msg = $"{nameof(LdapException)}: {base.Message} ({ResultCode}) {ResultCode.ToString().Humanize()}";
// Add server message
if (!string.IsNullOrEmpty(_serverMessage))
{
msg += $"\r\nServer Message: {_serverMessage}";
}
// Add Matched DN message
if (MatchedDN != null)
{
msg += $"\r\nMatched DN: {MatchedDN}";
}
if (Cause != null)
{
msg += $"\r\n{Cause}";
}
return msg;
}
}
}