Being the good programmers that you are you like to write your code so that it is as readable as possible, so you do things like qualifying your private instance variables with Me (this in C#) even though it’s optional. Sometimes you may even use the syntax “For i = x to y…next i” just to show which loop you are currently iterating. So it’s only natural, when throwing exceptions to want to specify the exception instance that you are throwing, for example Throw ex. What you may not realize is that there is a difference between “Throw ex” and “Throw”.
The runtime generates a stack trace and maintains it from the point at which the exception is thrown. Whenever you re-throw an exception the call stack is cleared to the point at which the exception was handled and re-thrown. Therefore to keep the stack trace intact when re-throwing an exception the correct syntax is to use the “Throw” keyword without specifying an exception.
Following is some sample code to demonstrate the point. Notice that in all methods except for Sub Main() the exception is re-thrown using simply “Throw”. When you examine the output Sub1(), Sub2() and Sub3() all maintain the entire stack trace. But when Sub Main() handles and re-throws the stack trace only includes the call to Sub1 and itself.
Module Module1
Sub Main()
Try
Console.WriteLine("Beginning Main()")
Sub1()
Catch ex As Exception
Console.WriteLine()
Console.WriteLine("Handling exception in Sub Main()")
Console.WriteLine(ex.Message)
Console.WriteLine(ex.StackTrace)
End Try
Console.ReadLine()
End Sub
Sub Sub1()
Try
Sub2()
Catch ex As Exception
Console.WriteLine()
Console.WriteLine("Handling Exception in Sub1()")
Console.WriteLine(ex.Message)
Console.WriteLine(ex.StackTrace)
Throw ex
End Try
End Sub
Sub Sub2()
Try
Sub3()
Catch ex As Exception
Console.WriteLine()
Console.WriteLine("Handling Exception in Sub2()")
Console.WriteLine(ex.Message)
Console.WriteLine(ex.StackTrace)
Throw
End Try
End Sub
Sub Sub3()
Console.WriteLine()
Dim i() As Integer = {1, 2, 3}
Try
For x As Integer = 0 To 3
Console.WriteLine(i(x))
Next x
Catch Ex As Exception
Console.WriteLine()
Console.WriteLine("Handling Exception in Sub3()")
Console.WriteLine(Ex.Message)
Console.WriteLine(Ex.StackTrace)
Throw
End Try
End Sub
End Module
When trying to install WinZip 11.1 on Windows Vista I was getting the error “Installation ended prematurely because of an error”. When I looked at the windows event log the error message read:
Windows Installer installed the product. Product Name: WinZip 11.1. Product Version: 11.1.7466. Product Language: 1033. Installation success or error status: 1603.
Apparently their installer requires VBScript and the vbscript.dll isn’t registered by default. In order to get the installer to run you must register vbscript.dll.
Here’s the command line that will register vbscript.dll:
regsvr32 "C:\windows\system32\vbscript.dll"
After registering I re-ran the installer and it installed successfully.
Enjoy!
Originally I had this problem more than a year ago but recently while developing a fairly robust ASP.NET 1.1 user interface I encuntered it again. This time though I was prepared and also thought that it was worthwhile writing a short post about.
You may have noticed that if you were to nest a Repeater control inside of another databound templated control, the ItemCommand() event does not fire for command buttons such as LinkButtons & ImageButttons that are inside of the Repeater. The reason is that the repeater is not bubbling up the event to the container control.
To solve the problem you can simply create a new class that derives from the Repeater control and override the OnBubbleEvent() method.
Here's the sample code:
Public
Class BubblingRepeater
Inherits System.Web.UI.WebControls.Repeater
Protected Overrides Function OnBubbleEvent(ByVal sender As Object, ByVal e As System.EventArgs) As Boolean
MyBase.OnBubbleEvent(sender, e)
End Function
End
Class
Now to add this control to a web page you'll need a <%@ Register %> directive. Here's a sample:
<%@ Register TagPrefix="MY" Namespace="MyNamespace" Assembly="MyAssembly" %>
Then instead of using an <asp:Repeater> tag in your code you insert a <MY:BubblingRepeater> tag like this:
<MY:BubblingRepeater>
<ItemTemplate>
Your content goes here...
</ItemTemplate>
</MY:BubblingRepeater>
That's it! Oh one last thing. The IDE will give you a warning on the <ItemTemplate> tag saying that "The active schema does not suport the element 'ItemTemplate'". Don't worry about that, it's more trouble to get rid of than it's worth.
Enjoy!
Here's a simple ASP.NET function that will get the opposite result of the Server.MapPath() function. This comes in handy when you're retrieving files recently saved by your web application. Pass it a fully qualified path and it returns a URL
Public Function MapURL(ByVal Path As String) As String
Dim AppPath As String = _
HttpContext.Current.Server.MapPath("~")
Dim url As String = String.Format("~{0}" _
, Path.Replace(AppPath, "").Replace("\", "/"))
Return url
End Function
Of course, you will have to make sure that the path is valid and the file is under the virtual root.
Enjoy!