ID:134917
 
Resolved
Error handling has been added. You can use the new keywords try and catch to setup error handling within a proc (it will also apply to procs called inside the try/catch). The new throw keyword can throw an error. And a new proc world.Error() can be overridden to handle errors at a global level--i.e., when no try/catch is available to handle them. See the DM reference for more details.
Applies to:DM Language
Status: Resolved (508.1287)

This issue has been resolved.
-> Not related to membership! Yay!

Will BYOND be getting error-handling features at any point? Are there any around at the moment? They can be rather useful. For example:

proc/IsTypePath(var/a)
OnError
return 0
new a
return 1


I think it would be a useful ability, but I'm not sure how difficult it would be to implement.
ASSERT() is probably your best bet, just give it an argument of something in the proc that NEEDS to be true and it'll crash the proc if it's not.
In response to Nadrew
But sometimes it's handy to use errors for other purposes, like that little procedure to check if something is a valid type path in my first post. If the proc crashes, it returns null, but you get the runtime-error messages and that's not something you want in a game. Additionally, the ability to customise error message output for general cases is handy. For instance:

proc/MyThingy(var/arg1,var/arg2,var/mob/bob)
OnError(var/list/l)
world << "Proc MyThingy crashed"
for(var/k in l) world << "[k] = [l[k]]"
return 0


So I think error-handling capabilities would be a handy thing for DM to have.
In response to Jp
If you're doing anything to cause a runtime error you should be notified of it and fix it. It's always very easy to prevent runtime errors.
In response to Nadrew
I think he wants it so that if he gets an error, the proc will advance to OnError, and do what's there.
In response to Ol' Yeller
He shouldn't be programming in a way to cause such errors.
In response to Nadrew
Nadrew wrote:
He shouldn't be programming in a way to cause such errors.

I disagree. C took this approach, and it's one reason why C's error handling sucks.

I wouldn't go with Jp's suggested syntax, though; rather, I'd go for the tried-and-true try/catch/finally (or try/except/finally) blocks, along with a throw (or raise) statement. And there would be an /exception type, which is created by the throw/raise statements and passed to the catch/except blocks.

Those familiar with the concept in other languages will probably have realised by now that I'm talking about exception handling. All modern progrmaming languages worth their salt have exception handling, and for good reason; being able to separate error checking into its own little blocks makes code a lot cleaner, and therefore a lot easier to maintain and debug. It also makes it FAR easier to "pass off" an error to the caller; an XML library, for example, shouldn't be expected to deal with file system errors; rather, that's the library's user's problem. With traditional error checking, the XML library *must* deal with the errors, or risk an ugly-looking crash message that the library user has no chance of preventing!

Indeed, I ran into just this problem when using Deadron's XML library in YAGSACG; when it reads a malformed XML document, it CRASH()es; and fair enough too, as there is no logical alternative. However, I got many bug reports from people who complained that my XML map loading system was broken. Upon closer inspection, it turned out that their XML was invalid. Exception handling would have allowed my program to catch those errors and tell them what they did wrong.

Granted, implementing exception handling would probably require a fair overhaul of some of BYOND's core functionality. But that doesn't make it a bad idea in itself; simply an impractical one.
In response to Crispy
Crispy wrote:
Granted, implementing exception handling would probably require a fair overhaul of some of BYOND's core functionality. But that doesn't make it a bad idea in itself; simply an impractical one.

I wonder. I'm not familiar enough with the way procs are called to be entirely sure, but I suspect some sort of error handling may indeed be possible. The question is how complex it will be. If it's feasible, it may be something Tom could handle, or me if I had time to puzzle it out.

Lummox JR
In response to Lummox JR
Lummox JR wrote:
I wonder. I'm not familiar enough with the way procs are called to be entirely sure, but I suspect some sort of error handling may indeed be possible. The question is how complex it will be. If it's feasible, it may be something Tom could handle, or me if I had time to puzzle it out.

I could see it as a future feature...as someone who's managed to go my entire 20+ year programming career almost never using exceptions, I'd be more interested in the time being put into other 4.0 features that I would absolutely use to great effect.
In response to Lummox JR
Lummox JR wrote:
I wonder. I'm not familiar enough with the way procs are called to be entirely sure, but I suspect some sort of error handling may indeed be possible. The question is how complex it will be. If it's feasible, it may be something Tom could handle, or me if I had time to puzzle it out.

That sounds great! I'd love to have proper exception handling in DM. =)
ARISE, old thread! For this feature will be implemented in BYOND 508!

var/ex
try
. = 2 + "a" // type mismatch
catch(ex)
world << "Caught exception: [ex]"
In response to Lummox JR
Oh man, no way! This is awesome Lummox JR. Now I'm really excited for 508.
Oh wow... nice.
This is not complete yet and will need more rigorous testing, but a proof of concept is working.
That legendary decade long topic bump tho.
How does this behave across function calls?
If you setup a try/catch in a proc, and then it calls another proc, and so on until there's an exception, all of the called procs will exit immediately as if they crashed, and the thrown value will go right to the catch.

This is an example from my test project (rewritten from memory):

mob/verb/TryTest()
try
TryTest2(2)
catch(var/ex)
world << "Exception: [ex]"

mob/proc/TryTest2(a)
a += "Hi"

The exception will be caught in TryTest().
I have not yet setup nested try/catch cases in the same proc, but the system is setup to allow that so it should work.
I'm assuming ex points to an event datum of sorts (with a name var), not just a string value?
In response to Super Saiyan X
Super Saiyan X wrote:
I'm assuming ex points to an event datum of sorts (with a name var), not just a string value?

Not a chance that's how it works. It's very likely just a string value.

Internally all there is is "CrashProc"
Page: 1 2 3