In addition to Daniel's point on the points of the sequence, it is worth looking at this further. If we take a simple function that repeats what you do
07 Function Method() As String 08 Try 09 Return "" 10 Catch ex As Exception 11 Return "" 12 End Try 13 End Function
In Debug, we get the following points in the sequence (I use OpenCover for this)
<SequencePoints> <SequencePoint offset="0" ordinal="0" uspid="261" vc="0" ec="32" el="7" sc="5" sl="7"/> <SequencePoint offset="1" ordinal="1" uspid="262" vc="0" ec="12" el="8" sc="9" sl="8"/> <SequencePoint offset="2" ordinal="2" uspid="263" vc="0" ec="22" el="9" sc="13" sl="9"/> <SequencePoint offset="19" ordinal="3" uspid="264" vc="0" ec="30" el="10" sc="9" sl="10"/> <SequencePoint offset="20" ordinal="4" uspid="265" vc="0" ec="22" el="11" sc="13" sl="11"/> <SequencePoint offset="40" ordinal="5" uspid="266" vc="0" ec="16" el="12" sc="9" sl="12"/> <SequencePoint offset="41" ordinal="6" uspid="267" vc="0" ec="17" el="13" sc="5" sl="13"/> </SequencePoints>
(where sl = start row, el = end row, sc = start column, ec = end column and offset = shift IL in decimal)
However, this only makes sense when you look at IL
.method public static string Method () cil managed { // Method begins at RVA 0x272c // Code size 43 (0x2b) .maxstack 2 .locals init ( [0] string Method, [1] class [mscorlib]System.Exception ex ) IL_0000: nop IL_0001: nop .try { IL_0002: ldstr "" IL_0007: stloc.0 IL_0008: leave.s IL_0029 IL_000a: leave.s IL_0028 } // end .try catch [mscorlib]System.Exception { IL_000c: dup IL_000d: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [mscorlib]System.Exception) IL_0012: stloc.1 IL_0013: nop IL_0014: ldstr "" IL_0019: stloc.0 IL_001a: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError() IL_001f: leave.s IL_0029 IL_0021: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError() IL_0026: leave.s IL_0028 } // end handler IL_0028: nop IL_0029: ldloc.0 IL_002a: ret } // end of method Module1::Method
Now that you see that the End Try line you are worried about is only marked as falling if you click on the IL command at offset 40 (IL_0028), however, when you look at IL, I cannot see how you ever ( leave.s is a small jump, such as an instruction that is used to exit try / catch / finally blocks), and if you follow the code, you will see that you always reach leave.s , which jumps to IL_0029.
The release of IL changes
.method public static string Method () cil managed {
as well as sequence points
<SequencePoints> <SequencePoint offset="0" ordinal="0" uspid="33" vc="0" ec="22" el="9" sc="13" sl="9"/> <SequencePoint offset="15" ordinal="1" uspid="34" vc="0" ec="22" el="11" sc="13" sl="11"/> <SequencePoint offset="28" ordinal="2" uspid="35" vc="0" ec="17" el="13" sc="5" sl="13"/> </SequencePoints>
This way you are free anyway, since now you will never see that your try / catch lines marked closed
So let's try changing your code, as Hans suggested, and return to debugging (because that's where you will get coverage from usually)
15 Function Method2() As String 16 Dim x As String 17 Try 18 x = "" 19 Catch ex As Exception 20 x = "" 21 End Try 22 Return x 23 End Function
Let's look at the points of the sequence again
<SequencePoints> <SequencePoint offset="0" ordinal="0" uspid="268" vc="0" ec="33" el="15" sc="5" sl="15"/> <SequencePoint offset="1" ordinal="1" uspid="269" vc="0" ec="12" el="17" sc="9" sl="17"/> <SequencePoint offset="2" ordinal="2" uspid="270" vc="0" ec="19" el="18" sc="13" sl="18"/> <SequencePoint offset="17" ordinal="3" uspid="271" vc="0" ec="30" el="19" sc="9" sl="19"/> <SequencePoint offset="18" ordinal="4" uspid="272" vc="0" ec="19" el="20" sc="13" sl="20"/> <SequencePoint offset="31" ordinal="5" uspid="273" vc="0" ec="16" el="21" sc="9" sl="21"/> <SequencePoint offset="32" ordinal="6" uspid="274" vc="0" ec="17" el="22" sc="9" sl="22"/> <SequencePoint offset="36" ordinal="7" uspid="275" vc="0" ec="17" el="23" sc="5" sl="23"/> </SequencePoints>
and IL
.method public static string Method2 () cil managed { // Method begins at RVA 0x282c // Code size 38 (0x26) .maxstack 2 .locals init ( [0] string Method2, [1] string x, [2] class [mscorlib]System.Exception ex ) IL_0000: nop IL_0001: nop .try { IL_0002: ldstr "" IL_0007: stloc.1 IL_0008: leave.s IL_001f } // end .try catch [mscorlib]System.Exception { IL_000a: dup IL_000b: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::SetProjectError(class [mscorlib]System.Exception) IL_0010: stloc.2 IL_0011: nop IL_0012: ldstr "" IL_0017: stloc.1 IL_0018: call void [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.ProjectData::ClearProjectError() IL_001d: leave.s IL_001f } // end handler IL_001f: nop IL_0020: ldloc.1 IL_0021: stloc.0 IL_0022: br.s IL_0024 IL_0024: ldloc.0 IL_0025: ret } // end of method Module1::Method2
So, in order for your End Try be closed, we need line 21 to be deleted, and this will be offset 31 (IL_001F), and since we can see the leave.s instructions go to that point, so now this the line will be marked as covered.
So, both Hans and Daniel are true, and I hope this explains why