SocketStream.WriteBytes

BlitzMax Forums/BlitzMax Beginners Area/SocketStream.WriteBytes

Retimer(Posted 2009) [#1]
Method WriteBytes( buf:Byte Ptr,count )
		Local t=count
		While count>0
			Local n=Write( buf,count )
			If Not n Throw New TStreamWriteException
			count:-n
			buf:+n
		Wend
		Return t
	End Method


Is
If Not n Throw New TStreamWriteException


Really a good thing?

I'm trying to run a server, and even though it checks if the connection is still alive before sending anything, I still get that runtime on a rare occasion - which crashes the server.


plash(Posted 2009) [#2]
I still get that runtime on a rare occasion - which crashes the server.
So slap a Try block around it.


Czar Flavius(Posted 2009) [#3]
Wanna play Catch?


Brucey(Posted 2009) [#4]
Wanna play Catch?

Heh :-)

Do like what Plash says.


plash(Posted 2009) [#5]
Really it should not be removed. There are many other cases where you'd rather want to get that exception.


skidracer(Posted 2009) [#6]
For server code you must catch all exceptions on all socket calls, having your server crash because a client disconnects / time-outs is not industry practice:)

Another issue you may have if you want to send large amounts of data is having buffers become full. IMHO the Write behavior of a socket (now blitzmax does multithreading) should be modified to block with timeout by default.

A SendBytes style method is possibly what you want in a single threaded environment, with this the condition of n<>count (or maybe just n=0) after the Write means REMAINING data should be scheduled for later transmission and exceptions for "socket no longer open" etc. can still be transmitted.


Retimer(Posted 2009) [#7]
Sorry for late response - I did just throw a try/catch within the writebytes function.

My post is more of a complaint that it raises a runtime error rather then raising an event, or returning an error. Instead, by default it is set to completely crash the app with the runtime error.

It's likely just me, but it seems like an inflexible way to have it set up.

This is the first time i've ever used a try/catch in blitzmax, as all my previous apps had more optimistic work-arounds, and were coded to not have to 'try' around errors, instead preventing them all together.

A check should be possible - but the only apparent way to check is failing 'socket.connected()'.


Brucey(Posted 2009) [#8]
it is set to completely crash the app

The only reason it appears to "crash" the app, is because you are not handling a raised exception.

I'm actually disappointed that the core BlitzMax modules don't utilise exceptions more than they do...
...and as a consequence, most of its users don't find them as useful as they should.


Retimer(Posted 2009) [#9]
The only reason it appears to "crash" the app, is because you are not handling a raised exception.


Fast response as usual Brucey.

I'm not sure I understand what you mean though. How am I to handle the exception, if even though a check is made, that there is still the possibility for it to raise the exception? Is that not something you can consider a bug?

You can handle the exception with a try, but why not prevent it from happening? Would that not be more professional?

I'm just confused that there appears to be a more global agreement FOR using try, when i've always thought it was frowned upon to use in any language (as a lazy way to prevent bigger issues).


Brucey(Posted 2009) [#10]
As skid alludes to, it may be that the buffer is full, and therefore, although the connection is open, you can't send any more data at that precise moment.

Of course, if the raised exception is bothering you so much, don't call WriteBytes :-)
Call Write() instead, and handle the "zero bytes written" issue yourself.

Otherwise, if the exception is thrown, you can either choose to ignore it and re-issue the call to WriteBytes() (it might succeed the next time, but if it continues to fail, maybe there is a fault), or perhaps handle it as a bigger problem in some way.


Brucey(Posted 2009) [#11]
i've always thought it was frowned upon to use in any language (as a lazy way to prevent bigger issues).

Certainly, you wouldn't normally use them for simple error checking in many cases, as they tend to carry a small overhead (I'm not sure what that is in BlitzMax's case though).
But imagine you have a function call which at some point could fail in several different ways, and you'd like to know in which particular way the call failed. One method might be to return an "error" object, which holds various status information - but then you can't return a value in your function. Another method might be to pass into the call that error object - so you have an extra param for each call. The other option, is to throw different exception from inside the function. You can catch-all, catch some, or catch none (and have it throw further up the chain if you need it to).

I've seen different APIs which handle errors in all these ways. I suppose it's just down to designer preference much of the time.

As an example of one API which prefers to raise exceptions - CEGUI, a call to addChildWindow(), can possibly throw - TCEUnknownObjectException, TCEInvalidRequestException or a TCEException (which is a catch-all, raised in case I've missed handling one thrown by the library).
FMOD, on the other hand, returns an Int, indicating the type of error (or zero for none), during the function call.

Each to their own :-)