when should I expect Catch not to catch errors?

Post

Posted
Rating:
#1 (In Topic #333)
Avatar
Regular
sjsepan is in the usergroup ‘Regular’
I have been using Catch in various parts of an app I am writing, and it mostly behaves as I'd expect, but when working with the gb.Settings[], I am running into a Catch that will not catch.

Although I can test for the null value that I am getting back from one particular settings scenario, it is the behavior of Catch that I am concerned with here. In the situation that an error is raised in a procedure that reads Settings, Catch will not be fired, even though Try … If Error will work.

In the sample case, if I try to read from a non-existing "qq" key, I get nulls, and depending on how the situation is coded, it may or not  be trapped. Individual Try … If Error code will work, but if I try to see the condition in a Catch (or even if I try to re-raise an new error in the If), Catch does not see it.

Please do not get side-tracked by whether my error-handling code is designed the way you would do it. What I am looking for here is an understanding of why Catch does not see the errors.
Thanks in advance!

UPDATE: FYI – if I originally had a difference between OpenFromSettings1 and OpenFromSettings2, multiple edits to try different approaches ultimately erased the difference before I posted the code, so discount the fact that there are two identical procedures.

CatchSettingsRead.conf:

Code

[x]
SomeString="strings!"
SomeBoolean=True
SomeInteger=30

[y]
SomeString="str"
SomeBoolean=True
SomeInteger=5

[z]
SomeString="1"
SomeBoolean=True
SomeInteger=2

output:

Code

False
OpenFromSettings1 not OK
------------------

False
OpenFromSettings2 not OK
------------------

False
Main.OpenFromSettings3.130: Type mismatch: wanted Integer, got Null instead
OpenFromSettings3 not OK


Main.module:

Code (gambas)

  1. ' Gambas module file
  2.  
  3. Public Sub Main()
  4.  
  5.     Dim sKey As String = "qq" '"x" "qq"
  6.  
  7.     If OpenFromSettings1(sKey) Then
  8.         Print "OpenFromSettings1 OK"
  9.     Else
  10.         Print "OpenFromSettings1 not OK"
  11.     Endif
  12.  
  13.     Print "------------------"
  14.  
  15.     If OpenFromSettings2(sKey) Then
  16.         Print "OpenFromSettings2 OK"
  17.     Else
  18.         Print "OpenFromSettings2 not OK"
  19.     Endif
  20.  
  21.     Print "------------------"
  22.  
  23.     If OpenFromSettings3(sKey) Then
  24.         Print "OpenFromSettings3 OK"
  25.     Else
  26.         Print "OpenFromSettings3 not OK"
  27.     Endif
  28.     Debug Error.Text
  29.     Print "anything"
  30.  
  31.  
  32. Public Function OpenFromSettings1(key As String) As Boolean
  33.  
  34.     Dim returnValue As Boolean = False
  35.     Dim sValue As String
  36.     Dim bValue As Boolean
  37.     Dim iValue As Integer
  38.  
  39.     If IsNull(key) Then
  40.         Error.Raise("OpenFromSettings1: Key is null")
  41.     Endif
  42.  
  43.     sValue = Settings[key & "/SomeString"]
  44.     Print sValue
  45.  
  46.     bValue = Settings[key & "/SomeBoolean"]
  47.     Print bValue
  48.  
  49.     iValue = Settings[key & "/SomeInteger"]
  50.     Print iValue
  51.  
  52.     returnValue = True
  53.     Return returnValue
  54.     Debug Error.Text
  55.     Print "anything"
  56.  
  57.  
  58. Public Function OpenFromSettings2(key As String) As Boolean
  59.  
  60.     Dim returnValue As Boolean = False
  61.     Dim sValue As String
  62.     Dim bValue As Boolean
  63.     Dim iValue As Integer
  64.  
  65.     If IsNull(key) Then
  66.         Error.Raise("OpenFromSettings2: Key is null")
  67.     Endif
  68.  
  69.     sValue = Settings[key & "/SomeString"]
  70.     Print sValue
  71.  
  72.     bValue = Settings[key & "/SomeBoolean"]
  73.     Print bValue
  74.  
  75.     iValue = Settings[key & "/SomeInteger"]
  76.     Print iValue 'IIf(IsNull(Settings[key & "/SomeInteger"]), 0, Settings[key & "/SomeInteger"])
  77.  
  78.     ' Try on statement followed by If Error will see error
  79.  
  80.     returnValue = True
  81.     Return returnValue
  82.     Debug Error.Text
  83.     Print "anything"
  84.  
  85.  
  86. Public Function OpenFromSettings3(key As String) As Boolean
  87.  
  88.     Dim returnValue As Boolean = False
  89.     Dim sValue As String
  90.     Dim bValue As Boolean
  91.     Dim iValue As Integer
  92.  
  93.     If IsNull(key) Then
  94.         Error.Raise("OpenFromSettings3: Key is null")
  95.     Endif
  96.  
  97.     Try sValue = Settings[key & "/SomeString"]
  98.     If Error Then
  99.         Debug Error.Text
  100.         Return False
  101.     Endif
  102.     Print sValue
  103.  
  104.     Try bValue = Settings[key & "/SomeBoolean"]
  105.     If Error Then
  106.         Debug Error.Text
  107.         Return False
  108.     Endif
  109.     Print bValue
  110.  
  111.     Try iValue = Settings[key & "/SomeInteger"]
  112.     If Error Then
  113.         Debug Error.Text
  114.         Return False
  115.     Endif
  116.     Print iValue 'IIf(IsNull(Settings[key & "/SomeInteger"]), 0, Settings[key & "/SomeInteger"])
  117.  
  118.     returnValue = True
  119.     Return returnValue
  120.     ' Catch
  121.     '     Debug Error.Text
  122.     ' Print "anything"
  123.  
  124.  
Online now: No Back to the top

Post

Posted
Rating:
#2
Avatar
Regular
cage is in the usergroup ‘Regular’
You might want to try what was pointed out to me.  As far as I have found it catches everything.

Code (gambas)

  1.   Catch
  2.     Message(Error.Text)
Try it and see if that helps.
Online now: No Back to the top

Post

Posted
Rating:
#3
Avatar
Regular
stevedee is in the usergroup ‘Regular’

sjsepan said

…but when working with the gb.Settings[], I am running into a Catch that will not catch….

That's an interesting problem Steve.

Can you tell me what happens when Catch fails to Catch?

i.e. if you step through the code, one line at a time, does the code just execute one line at a time all the way through and exit in the normal way, or does it jump to Catch but not execute the Catch code, or does it just exit-stage-left?
Online now: No Back to the top

Post

Posted
Rating:
#4
Avatar
Regular
sjsepan is in the usergroup ‘Regular’

cage said

You might want to try what was pointed out to me.  As far as I have found it catches everything.

Code (gambas)

  1.   Catch
  2.     Message(Error.Text)
Try it and see if that helps.

cage ,
Thanks for the idea.
So I went back to replace my Debug Error.Text with Message(Error.Text), but the compiler gently reminded me that I was illustrating this behavior in a console app, so I can't use Message without a gui component added. (I originally found it in a gui at running Qt forms, but clearly it's independent of Qt if it happens in the console)
That's actually a good thing, beause the only components in use are gb (required) and gb.Settings.
Steve

Attachment
Online now: No Back to the top

Post

Posted
Rating:
#5
Avatar
Regular
sjsepan is in the usergroup ‘Regular’

stevedee said

sjsepan said

…but when working with the gb.Settings[], I am running into a Catch that will not catch….

That's an interesting problem Steve.

Can you tell me what happens when Catch fails to Catch?

i.e. if you step through the code, one line at a time, does the code just execute one line at a time all the way through and exit in the normal way, or does it jump to Catch but not execute the Catch code, or does it just exit-stage-left?

stevedee ,
Good question…
So, stepping through, what I'd typically see, either in the console app that I used to re-create the behavior, or in the Qt gui where I first saw it, is that …
-it skips past remaining lines between the error location and before the Finally
-it executes the Finally
-it ignores anything in the Catch
-execution returns from the procedure
-and no error is caught in calling procedure either.

SteveS
Online now: No Back to the top

Post

Posted
Rating:
#6
Avatar
Regular
sjsepan is in the usergroup ‘Regular’
I think my next step is to try to eliminate gb.Settings from the equation.

I have been assuming that since I saw this only in a procedure with reads from Settings, that it may be involved. I need to recode a version of this console app that eliminates the use of the component and simply generates its own error in code (maybe a divide-by-0 or attempting to use a null in an integer)…

UPDATE: I removed the gb.Settings reference, changed the code to assign literal values instead of reading settings, removed the duplicate OpenFromSettings2 (for simplicity). Behavior still present; am I misunderstanding how Catch works?

sjsepan
________________


output:

Code

>somestring
>T
OpenFromSettings1 not OK
------------------
>somestring
>T
Main.OpenFromSettings3.72: Division by zero
OpenFromSettings3 not OK

Main.module:

Code (gambas)

  1. ' Gambas module file
  2.  
  3. Public Sub Main()
  4.  
  5.     If OpenFromSettings1() Then
  6.         Print "OpenFromSettings1 OK"
  7.     Else
  8.         Print "OpenFromSettings1 not OK"
  9.     Endif
  10.  
  11.     Print "------------------"
  12.  
  13.     If OpenFromSettings3() Then
  14.         Print "OpenFromSettings3 OK"
  15.     Else
  16.         Print "OpenFromSettings3 not OK"
  17.     Endif
  18.     Debug Error.Text
  19.     Print "anything"
  20.  
  21.  
  22. Public Function OpenFromSettings1() As Boolean
  23.  
  24.     Dim returnValue As Boolean = False
  25.     Dim sValue As String
  26.     Dim bValue As Boolean
  27.     Dim iValue As Integer
  28.  
  29.     sValue = "somestring" 'value OK
  30.     Print ">" & sValue
  31.  
  32.     bValue = True 'value OK
  33.     Print ">" & bValue
  34.  
  35.     iValue = 1 / 0 'value not OK; same Catch behavior tested w/ 1/0 and Null
  36.     Print ">" & iValue
  37.  
  38.     returnValue = True
  39.     Return returnValue
  40.     Debug Error.Text
  41.     Print "anything"
  42.  
  43.  
  44. Public Function OpenFromSettings3() As Boolean
  45.  
  46.     Dim returnValue As Boolean = False
  47.     Dim sValue As String
  48.     Dim bValue As Boolean
  49.     Dim iValue As Integer
  50.  
  51.     Try sValue = "somestring" 'value OK
  52.     If Error Then
  53.         Debug Error.Text
  54.         Return False
  55.     Endif
  56.     Print ">" & sValue
  57.  
  58.     Try bValue = True 'value OK
  59.     If Error Then
  60.         Debug Error.Text
  61.         Return False
  62.     Endif
  63.     Print ">" & bValue
  64.  
  65.     Try iValue = 1 / 0 'value not OK; same Catch behavior tested w/ 1/0 and Null
  66.     If Error Then
  67.         Debug Error.Text
  68.         Return False
  69.     Endif
  70.     Print ">" & iValue
  71.  
  72.     returnValue = True
  73.     Return returnValue
  74.     ' Catch
  75.     '     Debug Error.Text
  76.     ' Print "anything"
  77.  
  78.  

Attachment
Online now: No Back to the top

Post

Posted
Rating:
#7
Avatar
Guru
cogier is in the usergroup ‘Guru’
What is this line all about? Gambas does not seem to like it and I have not seen this type of syntax before.

<IMG src="http://www.cogier.com/gambas/ambigouous.png"> </IMG>
Online now: No Back to the top

Post

Posted
Rating:
#8
Avatar
Regular
stevedee is in the usergroup ‘Regular’
Steve, I think the problem is your "Finally" says "Return..". so that's what it is doing.

You would normally use Finally to do stuff like close files or destroy objects, but you are saying "whatever happens, return something" so the code does not reach Catch. Does that make sense?

If an error occurs, you don't really want to return anything because the value will probably be wrong. But if you must return a value its better to do something like this:-

Code (gambas)

  1. ...routine
  2.  
  3.  Close files
  4.  
  5.  Return x
  6.  
Online now: No Back to the top

Post

Posted
Rating:
#9
Avatar
Regular
stevedee is in the usergroup ‘Regular’
Just to underline what I'm saying, if you had code like this:-

Code (gambas)

  1.  
  2.     'Do stuff that creates an error
  3.  
  4.         GoTo Function 2
  5.  
  6.         'report error
  7.  
  8.         'do something else
  9.  
  10.  


I think you can see that the Catch code will never execute, because you are specifying a jump around it.

I hope that helps.
Online now: No Back to the top

Post

Posted
Rating:
#10
Avatar
Regular
sjsepan is in the usergroup ‘Regular’

cogier said

What is this line all about? Gambas does not seem to like it and I have not seen this type of syntax before.

<IMG src="http://www.cogier.com/gambas/ambigouous.png"> </IMG>

That was a typo from editing that I didn't catch before posting – please disregard. I've edited the earlier post to correct it.
Steve
Online now: No Back to the top

Post

Posted
Rating:
#11
Avatar
Regular
sjsepan is in the usergroup ‘Regular’

stevedee said

Steve, I think the problem is your "Finally" says "Return..". so that's what it is doing.

You would normally use Finally to do stuff like close files or destroy objects, but you are saying "whatever happens, return something" so the code does not reach Catch. Does that make sense?

If an error occurs, you don't really want to return anything because the value will probably be wrong. But if you must return a value its better to do something like this:-

Code (gambas)

  1. ...routine
  2.  
  3.  Close files
  4.  
  5.  Return x
  6.  

I see what you're saying. I guess I was used to .Net, which ran the Catch (think of putting out fires) before Finally (leaving and closing the barn door). ;-)
Since a function had to return something, I made sure that there was only one place where it did so.
Online now: No Back to the top

Post

Posted
Rating:
#12
Avatar
Regular
sjsepan is in the usergroup ‘Regular’

stevedee said

Just to underline what I'm saying, if you had code like this:-

Code (gambas)

  1.  
  2.     'Do stuff that creates an error
  3.  
  4.         GoTo Function 2
  5.  
  6.         'report error
  7.  
  8.         'do something else
  9.  
  10.  


I think you can see that the Catch code will never execute, because you are specifying a jump around it.

I hope that helps.

Yes. Very different from .Net, where you can't skip Catch, at least not so easily.  :-)
Online now: No Back to the top

Post

Posted
Rating:
#13
Avatar
Regular
sjsepan is in the usergroup ‘Regular’

stevedee said

Steve, I think the problem is your "Finally" says "Return..". so that's what it is doing.

You would normally use Finally to do stuff like close files or destroy objects, but you are saying "whatever happens, return something" so the code does not reach Catch. Does that make sense?

If an error occurs, you don't really want to return anything because the value will probably be wrong. But if you must return a value its better to do something like this:-

Code (gambas)

  1. ...routine
  2.  
  3.  Close files
  4.  
  5.  Return x
  6.  

I see what you're saying. I guess I was used to .Net, which ran the Catch (think of putting out fires) before Finally (leaving and closing the barn door). ;-)
Since a function had to return something, I made sure that there was only one place where it did so.

I made a change as you indicated, and it does indeed NOT skip out without running the catch. Thank You. I  will have to adapt my thinking going forward.
Steve
Online now: No Back to the top

Post

Posted
Rating:
#14
Avatar
Regular
sjsepan is in the usergroup ‘Regular’

sjsepan said

stevedee said

Steve, I think the problem is your "Finally" says "Return..". so that's what it is doing.

You would normally use Finally to do stuff like close files or destroy objects, but you are saying "whatever happens, return something" so the code does not reach Catch. Does that make sense?

If an error occurs, you don't really want to return anything because the value will probably be wrong. But if you must return a value its better to do something like this:-

Code (gambas)

  1. ...routine
  2.  
  3.  Close files
  4.  
  5.  Return x
  6.  

I see what you're saying. I guess I was used to .Net, which ran the Catch (think of putting out fires) before Finally (stacking and putting things away). ;-)
Since a function had to return something, I made sure that there was only one place where it did so.

I made a change as you indicated, and it does indeed NOT skip out without running the catch. Thank You. I  will have to adapt my thinking going forward.
Steve
Online now: No Back to the top

Post

Posted
Rating:
#15
Avatar
Regular
stevedee is in the usergroup ‘Regular’

sjsepan said

…I guess I was used to .Net, which ran the Catch (think of putting out fires) before Finally…

Try > Catch > Finally: that's the order for languages like C, PHP, Python, JavaScript….

(….otherwise, why is it called "Finally"?).

Can you think of another language (other than Gambas) where the order is the wrong way around?
So maybe this is the French way!
Online now: No Back to the top
1 guest and 0 members have just viewed this.