Catch?

BlitzMax Forums/BlitzMax Beginners Area/Catch?

doswelk(Posted 2006) [#1]
Local aValue$[] = ["Simon" , "Dave"]

Print "array length=" + Len(avalue)

Try

Print avalue[0]
Print avalue[1]
Print avalue[2]

Catch a$

Print a$

EndTry

Above is some sample code, why doesn't catch catch the error?

The example in the help seems to imply that catch will only catch an exception you throw yourself?


Yan(Posted 2006) [#2]
Local aValue$[] = ["Simon" , "Dave"]

Print "array length=" + Len(avalue)

Try
	Print avalue[0]
	Print avalue[1]
	Print avalue[2]
Catch exception:Object
	Print exception.ToString()
EndTry



doswelk(Posted 2006) [#3]
Thanks yan

That's more like what I was expecting, the more I look at the examples in the help files the less help i seem to get!

How do you get the code window?


Yan(Posted 2006) [#4]
Yeah, the try/catch command examples are a bit misleading. :o/

Have a look at 'Language>Exceptions', it's much more helpful.

What are the forum codes?


ImaginaryHuman(Posted 2006) [#5]
I use the code you use, with Catch A$ and print A$, seems to trap opengl errors okay.

Also did you get a catch when compiling with debug on?


Azathoth(Posted 2006) [#6]
Catch A$ won't trap anything other than strings being thrown, so it will fail on most exceptions.


Grey Alien(Posted 2006) [#7]
Try this code from my framework (you may need to modify it):

Function HandleGeneralError(o:Object)
	'This should be called inside the Catch section of a Try/Catch/End Try like this:
	'Try
	'  'some code
	'Catch o:Object
	'  HandleGeneralError(o)
	'  Shutdown()
	'End Try
	
	EndGraphics 'safety to ensure desktop isn't messed up
	ShowMouse() 'make sure user can click on dialog.
	
	'In debug mode, this will display a valid error message.
	'In non-debug mode (final release), this will show a dialog saying "memory execption error"
	'which is better than nothing.
	'In full-screen mode, this will still show a dialog on the desktop after the graphics mode
	'is ended, and when the dialog is clicked, the game will shutdown.
	If TBlitzException(o) Then
		Local Prefix$ = ""
		If DebugInt<> 0 Then Prefix = "("+DebugInt+") "
		Notify Prefix + TBlitzException(o).ToString()
	Else
		'Perhaps a string has been raised? If so, show it.
		Notify o.Tostring()
	EndIf
End Function



Azathoth(Posted 2006) [#8]
You can have multiple catch blocks:

Try 
	...
Catch a$
	...
Catch Ex:TBlitzException
	...
Catch b:Object
	...
EndTry



Dubious Drewski(Posted 2006) [#9]
Man, I've read the Blitz documentation, I've read these posts, I've programmed for a decade now
... but I still have no idea what Try and Catch do.


Perturbatio(Posted 2006) [#10]
I still have no idea what Try and Catch do.

If an error occurs inside the try..catch block, BMax throws an exception (which catch captures), you can then handle the error between the Catch and End Try block.


ImaginaryHuman(Posted 2006) [#11]
Hmm that's good to know, I didn't know I was only catching strings. Thanks.


doswelk(Posted 2006) [#12]
Ok; I understand the Try-Catch a bit better now, but...

Even with the code posted by "yan" or "Grey alien", the catch statement still does not catch the error in the code I posted.

Local aValue$[] = ["Simon" , "Dave"]

Print "array length=" + Len(avalue)

Try
	Print avalue[0]
	Print avalue[1]
	Print avalue[2]
Catch o:Object
	Print o.ToString()
EndTry


This still fails with a nasty application error "Attempt to index array element beyond array length".


Azathoth(Posted 2006) [#13]
It works if debug is on, maybe release mode doesn't generate the checking code?


Perturbatio(Posted 2006) [#14]
Try-Catch is a debug only thing (would be nice if it weren't), the docs should really be updated to reflect this.


Dreamora(Posted 2006) [#15]
That would make it totally useless as Try Catch is meant to give usefull error message if it fails in release mode?!

The problem with above examples: The Array out of bound check etc are only performed during Debug so they actually can not fire anything in release, they just break.


watusimoto(Posted 2007) [#16]
To Perturbatio: It appears that Try-Catch does work with both debug and release versions of BlitzMax programs. However, I believe the reason that doswelk's code broke during release version was that array bounds checking is disabled -- therefore no exception was thrown. If it had been thrown, I believe it would have been caught as expected.


H&K(Posted 2007) [#17]
Five Months, just to say exactly what the pevious post said ;)
Mind you Try-catch does need some more examples in the docs.


watusimoto(Posted 2007) [#18]
I think slowly ;-). When I read the thread I was left with the impression that Try-Catch was only debug mode, which is incorrect. I wanted to make it clear to subsequent readers that it works with release versions as well. But yes, after I posted, I realized that the array explanation had been pointed out by Dreamora. And I agree: more examples are needed, as well as examples of creating custom exception objects. So, here's one:

Type  invalidValueException Extends TBlitzException

	field msg:string = null

	Method toString:String()
		if msg then return msg else return "Invalid value!"
	End Method
End Type


And it's thrown like this:

function strToBool:byte(s:string)
	
	select s.toLower().trim()	
		case "true"
			return True
		case "false"
			return False
		default
			local e:invalidValueException = new invalidValueException
			e.msg = "Bad value passed: " + s
			Throw e 
	end select

end function


and caught like this:

try 
	b = strToBool(s)

catch ex:invalidValueException
	print ex.toString()
	' Do some error recovery things here

catch ex:object		' Catch other exceptions
	print ex.toString()
	' Do some other things here
end try