Try...Catch...Finally not firing finally?

D

David Lozzi

Howdy,

I ran into a very interesting issue and I'm curios as to how this is suppose
to work. I am using Try...Catch...Finally statements for all database
connectivity in my ASP.NET 2.0 web application. I'm connecting to IBM's
Universe 10.2 using UniObjects.Net. Anyway, if the connection errors, the
Finally closes the connection. What I see happening is that the function in
the Finally statement either isn't running or doesn't apply what its suppose
to.

For example. Running Visual Studio 2005, I debug my web app and step through
a function that I am purposly erroring on. The session opens, then a command
errors out. In the Catch I am taking the ex.tostring and sending it to a
class function that I then email that to myself and then send the user to a
default error page using server.transfer("page",false). After that function
runs, the debugger sends me back to the calling function, finishes the Catch
then fires the Finally, which closes the session.

So my problem is that it appears that the database session is not closing in
the finally. I just moved the close session to the first line in the Catch
and it appears to close it properly...

Thanks!!

David Lozzi
 
S

Samuel R. Neff

What exactly does the finally clause look like? Is it possible that
something within the finally clause is generating a second error
before the database "session" is closed (what do you mean exactly,
connection? if so use the using clause instead anyways).

Sam
 
B

bruce barker

server transfer aborts the current thread, so the finally will not fire.
you should not call it in a catch statement.

-- bruce (sqlwork.com)
 
S

Samuel R. Neff

Not true. The finally always runs.

protected void Page_Load(object sender, EventArgs e)
{
try
{
Log.Debug(this, "Throwing error...");
throw new Exception();
}
catch
{
Log.Debug(this, "Caught..");
Server.Transfer("gateway.aspx", false);
}
finally
{
Log.Debug(this, "Finally...");
}
}


produced..

2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Throwing
error...
2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Caught..
2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Finally...

Sam
 
A

Alvin Bruney [MVP]

The two conditions really aren't related - i don't think. Finally blocks
always fire, there's an implicit guarantee for that. True there was a bug in
1.1 that abrogated that guarantee, but it is fixed in 2.0. So the problem
would lie in the close code. It's quite possible that close is erroring out.
Put a trace from the db end to see if the close command is funneling thru to
the database engine.

--
Regards,
Alvin Bruney
------------------------------------------------------
Shameless author plug
Excel Services for .NET is coming...
OWC Black book on Amazon and
www.lulu.com/owc
Professional VSTO 2005 - Wrox/Wiley
 
D

David Lozzi

I ran a similar test instead used response.write() and it never reached the
finally........



Samuel R. Neff said:
Not true. The finally always runs.

protected void Page_Load(object sender, EventArgs e)
{
try
{
Log.Debug(this, "Throwing error...");
throw new Exception();
}
catch
{
Log.Debug(this, "Caught..");
Server.Transfer("gateway.aspx", false);
}
finally
{
Log.Debug(this, "Finally...");
}
}


produced..

2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Throwing
error...
2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Caught..
2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Finally...

Sam

------------------------------------------------------------
We're hiring! B-Line Medical is seeking .NET
Developers for exciting positions in medical product
development in MD/DC. Work with a variety of technologies
in a relaxed team environment. See ads on Dice.com.


server transfer aborts the current thread, so the finally will not fire.
you should not call it in a catch statement.

-- bruce (sqlwork.com)
 
D

David Lozzi

I ran a test using response.write() in each section of the try, and it never
reached the finally........

And the close works fine, it calls a simple
UniObjects.CloseSession(unisession). And when I moved it to the first line
of the catch it works fine everytime. We had a trace running on the DB end
and it kept saying that the session was never closed, no other errors.
 
A

Alvin Bruney [MVP]

Can you post a short sample application that demonstrates the problem, i'd
like to take a closer look.

--
Regards,
Alvin Bruney
------------------------------------------------------
Shameless author plug
Excel Services for .NET is coming...
OWC Black book on Amazon and
www.lulu.com/owc
Professional VSTO 2005 - Wrox/Wiley
 
D

David Lozzi

Sure, below. This is how it was, now the UOCloseSession function is before
the EmailError function.

Thanks!!


Public Function GetProduct(ByVal strPartNo As String) As Boolean
Dim uniSession As UniSession = Nothing

Try
uniSession = UOOpenSession()

Dim unicom As UniCommand = uniSession.CreateUniCommand
Dim subtext As String = ""
Dim qry As String = "LIST PARTS.WEB WITH @ID = " & strPartNo & "
DESC IMAGE DL.NOTES DISC_FLG GIFT_WRAP SIZEFLAG1 EXPECTED.DATE PRICE
MEDLEY_PARTS MEDLEY_IMAGES MEDLEY_STYLE PERSINSTR RELPARTS1 RELDESC1
PROD.TYPE TOXML ELEMENTS"
unicom.Command = qry
unicom.Execute()
subtext = Mid(unicom.Response, InStr(unicom.Response, "<"),
Len(unicom.Response))
unicom.Dispose()

........ stuff .......
Catch ex As Exception
EmailError("product_details.vb", "GetProduct", ex.ToString,
"Partno=" & strPartNo)
Return False
Finally
UOCloseSession(uniSession)
End Try


Public Shared Function UOCloseSession(ByRef unisess As UniSession)
UniObjects.CloseSession(unisess)
End Function


Public Shared Function EmailError(ByVal strPage As String, ByVal
strFunction As String, ByVal strError As String, Optional ByVal strOther As
String = "", Optional ByVal bolSend As Boolean = True, Optional ByVal
intLogType As Integer = 1)
If ConfigurationManager.AppSettings("ErrorEmailNotifications") =
True Then
If Not strError.Contains("viewstate MAC") Then
Dim msg As New MailMessage

msg.From = New
MailAddress(ConfigurationManager.AppSettings("ErrorEmailFrom"))

Dim toEmails() As String =
ConfigurationManager.AppSettings("ErrorEmailTo").Split(";")
For i As Integer = 0 To toEmails.Length - 1
msg.To.Add(toEmails(i))
Next

msg.Subject = "Error on " &
Current.Request.ServerVariables("SERVER_NAME") & " Website"
msg.IsBodyHtml = True
msg.Body = "<font face=verdana size='2'><b>Error on " &
Current.Request.ServerVariables("SERVER_NAME") & " Website!</b><br>" & Now()
& "<BR><br>" & _
"<b>Page Name:</b> " & strPage & "<br>" & _
"<b>URL:</b>" &
Current.Request.ServerVariables("URL") & "<br>" & _
"<b>Function Name:</b> " & strFunction & "<br><br>"
& _
"<b>Error Message:</b> " & strError & "<br><br>"

Dim smtpClient As New SmtpClient
smtpClient.Host = ConfigurationManager.AppSettings("SMTPServer")
smtpClient.Send(msg)
Current.Application("ErrorEmail") = Nothing
End If
Else
If Current.Application("ErrorEmail") Is Nothing Then
Dim msg As New MailMessage

msg.From = New
MailAddress(ConfigurationManager.AppSettings("ErrorEmailFrom"))

Dim toEmails() As String =
ConfigurationManager.AppSettings("ErrorEmailTo").Split(";")
For i As Integer = 0 To toEmails.Length - 1
msg.To.Add(toEmails(i))
Next

msg.Subject = "Errors are disabled on " & WebsiteName & "
Website"
msg.IsBodyHtml = True
msg.Body = "<font face=verdana size='2'><b>Error
notification is disabled on " & WebsiteName & " however an error occured!"

Dim smtpClient As New SmtpClient
smtpClient.Host =
ConfigurationManager.AppSettings("SMTPServer")
smtpClient.Send(msg)
Current.Application("ErrorEmail") = "done"
End If
End If

If bolSend Then
Current.Server.Transfer("~/oops.aspx", False)
End If

Return True
End Function
 
S

Samuel R. Neff

Have to be careful that the test is really testing what you think it
is. Testing with Response.Write() will test not only that the finally
is reached but also that the Response stream is still valid at that
point, which it isn't.

HTH,

Sam


------------------------------------------------------------
We're hiring! B-Line Medical is seeking .NET
Developers for exciting positions in medical product
development in MD/DC. Work with a variety of technologies
in a relaxed team environment. See ads on Dice.com.


I ran a similar test instead used response.write() and it never reached the
finally........



Samuel R. Neff said:
Not true. The finally always runs.

protected void Page_Load(object sender, EventArgs e)
{
try
{
Log.Debug(this, "Throwing error...");
throw new Exception();
}
catch
{
Log.Debug(this, "Caught..");
Server.Transfer("gateway.aspx", false);
}
finally
{
Log.Debug(this, "Finally...");
}
}


produced..

2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Throwing
error...
2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Caught..
2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Finally...

Sam
 
D

David Lozzi

Interesting.... So the Log.Debug, what does that do?


Samuel R. Neff said:
Have to be careful that the test is really testing what you think it
is. Testing with Response.Write() will test not only that the finally
is reached but also that the Response stream is still valid at that
point, which it isn't.

HTH,

Sam


------------------------------------------------------------
We're hiring! B-Line Medical is seeking .NET
Developers for exciting positions in medical product
development in MD/DC. Work with a variety of technologies
in a relaxed team environment. See ads on Dice.com.


I ran a similar test instead used response.write() and it never reached
the
finally........



Samuel R. Neff said:
Not true. The finally always runs.

protected void Page_Load(object sender, EventArgs e)
{
try
{
Log.Debug(this, "Throwing error...");
throw new Exception();
}
catch
{
Log.Debug(this, "Caught..");
Server.Transfer("gateway.aspx", false);
}
finally
{
Log.Debug(this, "Finally...");
}
}


produced..

2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Throwing
error...
2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Caught..
2007-04-24 12:22:46.98 [2276] DEBUG ASP.default_aspx - Finally...

Sam
 
S

Samuel R. Neff

Log.Debug is simply a static wrapper around log4net which I have
configured to log to a text file.

Sam

------------------------------------------------------------
We're hiring! B-Line Medical is seeking .NET
Developers for exciting positions in medical product
development in MD/DC. Work with a variety of technologies
in a relaxed team environment. See ads on Dice.com.
 
A

Alvin Bruney [MVP]

Finally blocks going off like clock work on my end. I had to convert your vb
in c# and stub some methods. I simply threw an exception in the constructor
of the unisession object to duplicate your issue.

--
Regards,
Alvin Bruney
------------------------------------------------------
Shameless author plug
Excel Services for .NET is coming...
OWC Black book on Amazon and
www.lulu.com/owc
Professional VSTO 2005 - Wrox/Wiley
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,013
Latest member
KatriceSwa

Latest Threads

Top