I recently spoke with a developer who was upset that the redundancy he built into his Web application had failed him. As a safeguard against database failure, he had written a script which wrote new entries to a log file on the local file system as well as adding them to the database. It was a good idea… unfortunately the implementation wasn’t so good.
The fact that he was writing to the log file first gave him a false sense of security. You see, every time there was a problem with the database he’d always gone to check the log file and found the missing entries there waiting. The problem didn’t become apparent until someone accidently changed the permissions on the log file and his script threw an ‘access denied’ error which halted execution. It never even tried to write to the database and the new entries were lost completely. So what did he do wrong?
He never added any error handling to the script. If he had simply added a “Try… Catch… Finally” block around each of the operations, the script would have achieved the desired result. Even if he didn’t take the time to do anything to actually handle the errors, execution would have continued and the script would have at least tried to write the new entries to the database instead of coming to a dead stop when it ran into the permission problem.
For those of you who aren’t familiar with “Try… Catch… Finally”, here’s a short sample script which illustrates my point. This script attempts to write to a log file and send an email. I’ve wrapped both operations with a “Try… Catch… Finally” block so if either (or both) fail, as they probably will if you try and run the script as is, execution will still continue to the end of the script. For illustration I’ve included status messages which the script will display as it runs. It’ll also output the text message of any errors it encounters at the bottom of the page.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
‘ Try to write to a logfile and send an email, writing status messages as we go…
litPageProgress.Text = “
Page_Load sub started execution at: ” & _
Now().ToString & “
” & vbCrLf
litPageProgress.Text = litPageProgress.Text & “
Attempt to write to log file… ”
Try
File.AppendAllText(Server.MapPath(“logfile.log”), Now())
litPageProgress.Text = litPageProgress.Text & “Succeeded!”
Catch exLogFile As Exception
litErrors.Text = litErrors.Text & exLogFile.Message & “
”
litPageProgress.Text = litPageProgress.Text & “Failed!”
Finally
litPageProgress.Text = litPageProgress.Text & “
” & vbCrLf
End Try
litPageProgress.Text = litPageProgress.Text & “
Attempt to send email… ”
Try
Dim mySmtpClient As New SmtpClient(“localhost”)
mySmtpClient.Send(“FROM_ADDRESS”, “TO_ADDRESS”, “Message Subject”, “Message Body”)
litPageProgress.Text = litPageProgress.Text & “Succeeded!”
Catch exLogFile As Exception
litErrors.Text = litErrors.Text & exLogFile.Message & “
”
litPageProgress.Text = litPageProgress.Text & “Failed!”
Finally
litPageProgress.Text = litPageProgress.Text & “
” & vbCrLf
End Try
‘ Note that this line will still run even if errors occur above.
litPageProgress.Text = litPageProgress.Text & _
“
Page_Load sub ended execution at: ” & _
Now().ToString & “
” & vbCrLf
End Sub
Try… Catch… Finally Error Handling Example
Errors Encountered: