Try, Throw, Catch.. ?

BlitzMax Forums/BlitzMax Programming/Try, Throw, Catch.. ?

Gabriel(Posted 2006) [#1]
I think I understand how to use them, but I don't have the first clue why they're useful. The example in the documentation is just about ( barely ) enough to figure out how to use them, but it's not even close to justifying the use of them.

Rem
Throw generates a BlitzMax exception.
End Rem

Try
	repeat
		a:+1
		print a
		if a>20 throw "chunks"
	forever
Catch a$
	print "caught exception "+a$
EndTry


Great. This does the same thing.

Rem
Throw generates a BlitzMax exception.
End Rem

	repeat
		a:+1
		print a
		if a>20 ThrowException("chunks")
	forever

Function ThrowException(ex:string)
	print "caught exception "+ex
End Function


The only advantage to the former is that you don't have to keep a track of which exception function you're going to throw. Although it's swings and roundabouts because you might end up with some pretty complex nests of Try and EndTry blocks which are just about as much work as keeping track of which throw function to use.

So there has to be more than this to it, or it wouldn't be there. But having read the docs and searched the forums, I can't find anything.

Perhaps the people writing the docs would understand the issue better if I compared this to pointers. I always knew what pointers were. I always knew how to use them. It just took me bloody ages to figure out WHY I should use them. It's the same here. I'm sure that C# and Java programmers just picked it up and ran with it, but I'm not one, and it might be nice to have some idea of the *real* purpose.


Azathoth(Posted 2006) [#2]
Throwing from Constructors or functions/methods that don't or can't return values?


Gabriel(Posted 2006) [#3]
Throwing from Constructors or functions/methods that don't or can't return values?

The second version doesn't do that either.


Mark Tiffany(Posted 2006) [#4]
It can be used for handling "expected errors".

You can throw an exception anywhere you like. That will then cause the error to be passed up the call stack until it is either handled or the program ends (with an error).

Some would view it as bad (or lazy) coding if you need to resort to exceptions - the thinking being you should return error codes or explicitly code for the issue..


Gabriel(Posted 2006) [#5]
the thinking being you should return error codes or explicitly code for the issue..

This is very much what I'm thinking as I'm looking at it. If I know where a problem may occur, through user stupidity or just something beyond the control of the program ( loading a file which is of the wrong type, despite beind named correctly or something ) then it seems it would be better and just as easy to write proper handling code for that problem and do something intelligent instead.


Fry Crayola(Posted 2006) [#6]
They can be useful in prototyping, when you want to fire out working code, even when you know there's a likelihood of an error, and code cleanliness isn't an issue.


Tom Darby(Posted 2006) [#7]
They can be useful in a public release, too: if you handle errors gracefully, you can give users something more than "the game crashed" when they report back to you.

In my current project, I've wrapped pretty much everything in try/catch blocks; if a procedure throws an error, I send the source file name, the type.method() or function(), and the error message itself to a function which kicks it into a text file, notifies the user (in plain English) of an unexpected bug, tells them where the text file is, and to send it to me. Then, the program exits gracefully.

For any decent-sized project, you're gonna have some bugs in your code, no matter how careful you are. Robust error-handling will help you debug problems from users--and it'll also help users feel less threatened by things going "wrong" in your program.