We have a C# project, which interacts with Active Directory services.
For the context : we use objects from the System.DirectoryServices.Protocols namespace, namely :
We got stuck for some time on understanding an error which triggered a DirectoryOperationException, before realizing the description of the error what not included in the exception.Message
, but was nested further down in the exception object.
We used to have a very simple exception logging when catching such an error :
catch (DirectoryOperationError de) {
log("ERROR directory error {0} : {1}", de.GetType(), de.Message);
throw;
}
We now have the following code :
catch (DirectoryOperationException de)
{
log("ERROR directory error {0} : {1}", de.GetType(), de.Message);
var resp = de.Response;
if (resp == null)
{
log(" -- no response object linked to exception --");
throw;
}
log("ERROR directoryresponse error message:'{0}'", resp.ErrorMessage);
int errorCode;
var hexCode = resp.ErrorMessage.Substring(0, 8);
if (!int.TryParse(hexCode, System.Globalization.NumberStyles.HexNumber, null, out errorCode)){
log(" -- could not figure out error code from '{0}' --", hexCode);
throw;
}
var win32exception = new System.ComponentModel.Win32Exception(errorCode);
var msg = win32exception.Message;
log("ERROR errcode:{0} : {1}", errorCode, msg);
throw;
}
which ranks pretty high on my "hocus pocus" scale (especially the part where we rely on the string message beginning by an 8 char long hex integer).
Question
Is there a more direct way to access the underlying LDAPError and translate it into a meaningful message using C# ?
Coming back to this question :
I realized that going through a standard LDAP layer to communicate with the server would only get me a standard LDAP Result, e.g a struct with basically one LDAP error code (the resultCode
field) and a message string (the diagnosticMessage
field).
Perhaps Active Directory could have added controls in its response that would indicate AD specific informations, but it looks like it doesn't.
So all in all, I don't think there can be a much better way to decode that error message : a library would probably just apply a similar treatment on the message string alone, and hope that it is decoding a message coming from an Active Directory -- not a message coming from an OpenLDAP or Novell or whatnot implementation, that happens to start with a valid 8-char hex code.
In our case: since our requests also included controls heavily linked to AD (DirSync controls), the confidence of talking to an Active Directory was basically 100%.
Instead of going through an LDAP connection, I could perhaps have gone through a Win32 API specific function, which could return the Win32 error code as a value, but I haven't had the opportunity to test this when we were faced with this issue.
for reference, a list of possible Win32 error codes is listed here