C#:
private
static void VerifyCredentials(SecureUser
pUser,
string pUsername, string pPassword, string pDomain) {
if
(pUser.IsNullEntity) {
throw
new LoginException(
LoginExceptionType.InvalidUserName, null, pUsername);
}
if
(pPassword != pUser.UserPassword)
{
throw
new LoginException(
LoginExceptionType.InvalidPassword, null, pUsername);
}
}
VB
.Net:
Private
Shared Sub VerifyCredentials(ByVal
pUser As SecureUser, _
ByVal pUsername As String, ByVal pPassword As String, _
ByVal pDomain As String)
If
(pUser.IsNullEntity) Then
Throw
New LoginException(
_
LoginExceptionType.InvalidUserName, Nothing, pUsername)
End If
If
(Not pPassword = pUser.UserPassword)
Then
Throw
New LoginException(
_
LoginExceptionType.InvalidPassword, Nothing, pUsername)
End If
End Sub
We
run it within Visual Studio, configured
for debugging. We deliberately
enter the incorrect username. The
debugger halts unexpectedly in
the middle of the LoginManager
like so:
This
message is destined for the client
but we're stuck here inside LoginManager.
If
we understand what is happening,
we know we can press [F5] to continue.
But this halt is disconcerting
at the least and more often than
not we'll waste a few hours rooting
around for a bug that is not there.
Solution:
Let's
add an attribute to our method:
C#:
//
Let the client catch exceptions.
[System.Diagnostics.DebuggerHidden()]
private
static void VerifyCredentials(SecureUser
pUser,
VB
.Net:
'
Let the client catch exceptions.
<System.Diagnostics.DebuggerHidden()> _
Private Shared Sub VerifyCredentials(ByVal pUser As SecureUser, _
There
is progress: the debugger no longer
stops us inside the VerifyCredentials
method.
But
now the debugger stops us in the calling method,
Login. The attribute was only effective
for the VerifyCredentials method,
not its caller.
Unfortunately,
we can't decorate the call to VerifyCredentials
with the attribute.
//
It won't compile. We can't decorate
method call with an attribute.
[System.Diagnostics.DebuggerHidden()]
VerifyCredentials(aUser, username, password, domain);
But
we can add the attribute to the calling method:
In
C#:
//
Let the client catch exceptions.
[System.Diagnostics.DebuggerHidden()]
public IPrincipal Login(ILoginCredential pCredential, ...
VB
.Net:
'
Let the client catch exceptions.
<System.Diagnostics.DebuggerHidden()> _
Public Function Login(ByVal pCredential As ICredential, _
Now
when we run it, the debugger lets
the exception escape both VerifyCredentials
and Login. The Login Dialog catches
it and displays the message as
intended, as shown at the top of
this tip.
Caveat: You
will not be able to debug into
a method tagged with this attribute!
Remember to comment out the attribute
before setting a breakpoint in
Login or VerifyCredentials.
|