ID:2472559
 
I've recently been trying to build some more robust code which is less prone to runtime errors caused by players closing the game in the middle of doing something. Some things I've been working on lately involve a lot of user input, and while blazing through it all I've found myself using the classic

if(!src)
return


But slowly I've seen the number of that snippet grow to fairly ridiculous amounts, especially when a decision is made involving multiple entities. if(!this), if(!that), if(!everything). The next step I thought about was to encase everything in try/catch blocks, though I have very many individual objects and turfs that contain these checks, and adding all of these try/catch blocks seems like it'd be a lot of extra indentation and still extra code. Then, I thought about modifying world/Error() to deal with this, and thought I'd check in here before doing anything too drastic.

I can live with NPC mobs or objects finding weird ways to obliterate in the middle of being useful. That can be fixed. My main issue is with players leaving while doing things, immediately chucking null references and fracturing things. Truth be told, often times this is just me trying to keep the error log clean of players logging out mid-conversation of an NPC or something of the like. Is it advisable to use world/Error() to catch and promptly ignore null references thrown by players, or is this taboo too unsafe to be broken for convenience purposes? Alternatively, what methods have you all used and seen for dealing with players leaving while doing things? Try/catch, conditional checks, etc?
You can either do the reference checking, or keep the player mob around until everything it's doing is finished. One is tedious and gets ugly when it comes to code readability, the other is fairly complicated to manage but once it's set it's usually a good way to go.

There are a lot of cases when you want a runtime error to happen though, then you'd fix the underlying cause of that reference being null. The cases you mentioned aren't really in that category, but it's a good idea to keep track of which ones are going to be gracefully handled by simply checking if the reference is valid and the ones that should never be executed with those problems in the first place.

For example, if you have MyProc() crashing with a null reference, you shouldn't have an if(!reference) in MyProc(), you should be finding places where said reference can be null when calling MyProc(), those are the places you'd handle things because that's where you'd want to figure out why that reference isn't what it should be.
Surprise nulls also appear more often if you use del a lot. Since the purpose of del is to check potentially every possible reference in the game (every variable of every object that exists, including every index of every list) for the object being deleted and set them to null until the object has no more references, del will cause all references to a deleted object to become null, even if that object is currently "in use" by some other unrelated proc.
In response to Nadrew
Yeah that's pretty much what I had in mind. I do what I can to ensure that references are never null when it can be avoided, but that leads directly to what I posted about, the one thing you can't ever fully control: players. I have thought about leaving the mob around for a while, though quite a few of my code snippets wouldn't particularly benefit. This is why I'm looking for creative suggestions on how to deal with players DCing all over the place

From what I can see from
http://www.byond.com/forum/post/1948322#comment16867278

I see that the client already disconnects from the mob by the time Logout() is called. This is fine, I don't need the client. If I were to leave the mob hanging around, what may be an easy way to determine when they're safe to be deleted? This may be going far out of scope, I understand. I can't imagine it is as simple as having a DoNotDelete() proc set attached to players, with other procs flipping that when needed, keeping Logout() stuck in a loop until all procs have authorized its release; if one proc manages to crash or loop in a way not allowing the deletion of the mob, it could be stuck floating around forever. This could be perhaps resolved with try/catch blocks, but then we go back to my original point of attempting to avoid placing those everywhere.

Hm.
In response to SeymourG
Objects are automatically deleted when there are no more references to them, using a reference-counting garbage collection system. In other words, objects cease to exist when there's essentially nothing using them, so you never actually have to use del in your code even once.
I wound up creating a child thread in the Developer Help forum to continue this post, before I abruptly leave the scope of this one.

http://www.byond.com/forum/post/2472758