How does Try/Catch work?
BlitzMax Forums/BlitzMax Programming/How does Try/Catch work?
| ||
I'm new to this aspect of error detection, so bare with me. I have a program that needs to read some data from disk into a data structure. I want to be able to catch a file error such as reading beyond the end of the file, etc, so I thought I could put the ReadShort()s/ReadLong()s, etc inside a Try/Catch block and I could nab an error before it causes major problems. Take a look at the following test code: t:TStream = WriteStream("testfile.bla") WriteLong(t,20000) WriteLong(t,30000) CloseStream(t) Try u:TStream = OpenStream("testfile.bla") a:Long = ReadLong(u) b:Long = ReadLong(u) c:Long = ReadLong(u) ' Does not cause an error! d:Long = ReadLong(u) ' Neither does this! Catch err:TStreamReadException If err <> Null Then End ' This line is never executed EndTry Print a Print b Print c Print d CloseStream(u) The third and fourth Readxxxx() lines simply return zero (which I suppose could be handy in some situations), so how can I distinguish between an error zero and a legitimate value of zero read from the file? According to the docs, if ReadShort() etc can not read enough data, they throw a TStreamReadException error. So how do I 'catch' that error and act accordingly? Thanks, Russell |
| ||
Something doesn't seem right here... For a better example on how to use Try/Catch: SuperStrict Framework brl.standardio Import brl.stream Try Throw New(TStreamReadException) Catch e:Object Print e.ToString() End End Try End |
| ||
so bare with me Much as I like this forum, I'm not getting naked. |
| ||
This should help http://www.cplusplus.com/doc/tutorial/exceptions.html |
| ||
You example doesn't raise an exception because EOF has been reached after the second ReadLong(). This causes, internally, ReadBytes() to return 8, and not throw an exception. One way to get the execption is to ReadInt() on the second read, and then on the third, ReadLong(). One might consider this a bug, since now you have reached EOF, you can keep "reading" without error. Then again, perhaps you are meant to check EOF after every read. But supposedly, you might also consider that an exception would be thrown if you tried to read past the end of the file - if EOF was true or not. But Try/Catch in BlitzMax generally works well. You can even throw them from C/C++, which is cool :-) |
| ||
Slightly clearer than muddy water, but... So I have to 'Throw' the error-potential for it to be caught (using Plash's example)? I'll have a look-see at your example. So does anyone have a tried-and-true method for safely reading large files that may have been corrupted (and therefore are not the size they should be)? Thanks Russell |
| ||
So I have to 'Throw' the error-potential for it to be caught (using Plash's example)? I'll have a look-see at your example. Uh, no. That's not what I intended, I was just trying to show you how it works. You can just accept the exception as an object and type-cast it to figure out which kind of stream error it is. |
| ||
Thanks Plash. I don't get why reading past the end of the file doesn't cause any errors, though. I have an idea for another method, but Try/Catch may still have a use if I can get to work the way I want. Russell |
| ||
I don't get why reading past the end of the file doesn't cause any errors, though Because your read requests use up precisely the amount of data available. You wrote two longs, and you read two longs. At this point, it makes a note that the the end of the file has been reached. On future reads, it does not attempt to read anything because it knows it reached the end of the file. It doesn't try to read, so there can be no error. |
| ||
On future reads, it does not attempt to read anything because it knows it reached the end of the file. It doesn't try to read, so there can be no error. Yes, but it should throw the exception to tell you it is out of data. |
| ||
Yes, but it should throw the exception to tell you it is out of data. Indeed. It should at least be consistent. |
| ||
Yes, but it should throw the exception to tell you it is out of data. If you mean it should be rewritten to ensure that it does do that, I agree, it should. It's very random to behave differently depending on whether it runs out of data in the middle of an operation or at the end of one. |
| ||
Well, Try/Catch doesn't work as I would expect it to. I was hoping it would work like other language's OnError libraries (such as Purebasic's, although it is only in the Windows version):Procedure ErrorHandlingFunction() blah blah blah EndProcedure OnError(@ErrorHandlingFunction) ..and then any errors that occur will call the function automagically :) Try/Catch seems to require me to throw the error instead of Bmax? Weird. Anyway, I found another way to do it. But OnError() would be quite handy (and easier to use). Russell |