Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Discussion on Exception Handling

Name: Anonymous 2012-01-27 15:56

What does /prog/ think of exception handling, as opposed to other methods such as return values or a global error variable/object? Personally, I think that exceptions in languages like C++ and Java have really introduced a much better method of handling errors that is language-independent. It makes your code infinitely more concise and readable, and now your errors actually have meaning beyond 0, "", null, etc.

I'm in my first year of computer programming at a local university, and we're just learning about exceptions now. It was like the world opened up; I couldn't believe how I could have accomplished anything before this, not knowing about exception handling. Never again will I have to use archaic methods of error handling.

Name: Anonymous 2012-01-27 16:10

Throwing exceptions that way is bad.

In C++, you have to make sure that your code can handle any possible exception that could be thrown. Also, the only way to know that a code can throw an exception is to read the source. That way, you may often forget to handle a specific exception in a function and your whole program comes down crashing. Java fixes that by requiring most exceptions that a method can throw (there are some exceptions to that) to be declared in the method prototype.

Another huge problem with exceptions is that they're often used to delegate the error handling upwards in the function stack, throwing away all further execution of the functions that don't handle that exception. Wouldn't it be better that the first parent function handles it, except if the exception is truly exceptional?

That brings me to another point: exceptions aren't used only for exceptional errors, but for any error that may arise overall. Often, one would write code that handles a simple side error (that doesn't require return from the current function, but only diminishes its functionality a bit) and a worse error (that makes the execution of that function and possibly the whole process impossible) in the same way, while there's no reason to do that in the first place.

Go approaches this problem in a better way: to signal an error, simply use the multiple return to return an error type next to the normal return values (which can be set to their null values if they cannot be computed or something), which is nil if there's no error and error message (possibly with more fields) otherwise. That way, you always know that a function may return an error, you don't risk missing undeclared errors, you don't have to exit the current function if you want it to signal an error on return and your program crashing and you can handle errors in better ways (you can even return multiple errors). Also, delegating errors to other functions requires work rather than be explicit. If an error is truly exceptional (assert(0); exceptional), you can still use panic and recover to use exceptions-like features.

Name: Anonymous 2012-01-27 16:31

errno is better

Name: Anonymous 2012-01-27 16:44

Exceptions are just glorified gotos.

int func(void)
{
    if(!do_some_stuff()) {
        goto exception; // throw exception;
    }
    do_stuff_if_successful();
    return result;

exception: // catch exception before returning
    clean_up();
    return error; // just to signal, don't leave cleanup to caller
}


By the way, the above is probably the only acceptable use of goto.

Name: Anonymous 2012-01-27 16:54

>>3
It's also several orders of magnitude faster than exceptions.

Name: Anonymous 2012-01-27 17:04

>>4

how do i loop without goto??

Name: Anonymous 2012-01-27 17:05

>>6
while and for are typically used for that kind of harmful behavior

Name: I_STILL_HAVE_A_JOB !!qmiXqQhekkGXVVD 2012-01-27 17:06

>>5
With two tin cans and a rope.

Name: Anonymous 2012-01-27 17:52

all errors should cause immediate termination of the process. NO CATCHING ALLOWED

Name: Anonymous 2012-01-27 18:08

>>9
That's best practice in Erlang!

On error get flushed and drag your minion processes down with you into a pit to hell, and some god process gets word and appoints some other process to fix your mess.

Just like governments, management in businesses, and villains in most anime.

Name: Anonymous 2012-01-27 18:19

I like FIOC's method: exceptions, exceptions everywhere!

Name: Anonymous 2012-01-27 18:59

ONE WORD:FORCED OVERHEAD OF EXCEPTION DRIVEN PROGRAMMING

Name: Anonymous 2012-01-27 19:22

I generally think its a load of guff..  There's nothing wrong with the "checking-return-code-paradigm" so why do we need anything else. It's just cock-munching faggot bullshit.

Name: Anonymous 2012-01-27 22:12

so why do we need anything else
Because other paradigms are valid too. Exceptions are usually frustrating and prone to boilerplate or negligence, but they're not the only way.

Erlang was mentioned, and while has exceptions, the crash and respawn mechanism goes down smooth.

Someone on the Go team made an enlightened post (I was shocked!) about exceptions. They were discussing a library (a json parser iirc) which permitted no exceptions to escape the library. It would be interesting to see something that restricts exceptions to within a compilation unit.

In OCaml you might be tempted to use exceptions, but you can use tagged returns instead. Now the exceptional case is typechecked like everything else. You'll have to address it  one way or another (you can match on _, but even that cop-out documents the fact that your code is willing to throw things away—whereas not handling an exception has no documented absence.) It's equivalent to checking a return code except you have a separate band for errors. It's also equivalent to exceptions in the sense that if you do not handle that case it will actually raise a match error should it ever occur. It will also warn during compilation if you write matches that are not exhaustive.

You can do this fairly naturally in C too, although it won't be checked by the compiler. Your return type would be something like a struct with an enum (tag) and a union (results, covering each tag type.) In dynamic languages it's even easier with things like typeof(), but they are even harder to be sure of correctness.

Name: Anonymous 2012-01-27 22:30

I think most errors should be handled with assertions. Establish and document the appropriate preconditions for every routine, and make sure they are never violated. With these assumptions, you can obtain the maximum performance by cutting out the error checking in the non debug version of the executable. Horrible things will happen if the error does occur though, so you have to be careful.

If the verification of the precondition is difficult and easier to do from within the algorithm, then I think return codes are sufficient. It is like turning:


if cool(G) {
  algorithm1(G);
} else {
  algorithm2(G);
}


into:


if(!algorithm1(G)) {
  algorithm2(G);
}


where algorithm1 becomes:


bool algorithm1(G) {
  ...
  ...
  if(it became evident that G is uncool) {
    clean up stuff.
    return false;
  }
  ...
  ...
  return true;
}


Sometimes that can be more efficient than using the cool function to inspect G and determine which algorithm is appropriate. But if you know in advance that algorithm1 should work, then you should give yourself the ability to cull the error checking somehow.

One alternative to exceptions is to pass in an error handler object. I believe this is similar to conditions in lisp, but it has been a long time since I've looked at those.

Name: Anonymous 2012-01-28 21:42

C++ style exceptions are only a non-local dynamic control transfer mechanism. There is little in the way of recovery possible.

Before a "handler" executes, the stack must be unwound back to the dynamic point where the handler was established. This process discards valuable information, making it impossible to return to the place where the error situation occurred and choose an alternative future execution path (i.e. recover).

Real exception handling means that you keep all information about the program until a decision can be made about how to recover. This means that handlers execute in a new context, prior to unwinding taking place.

PL/I conditions are like this. If a PL/I handler ("on block") returns, then the error code is basically retried (if you do this for something like division by zero, the behavior is undefined).

Lisp conditions are like this. Condition handlers are dynamically registered on the stack, but when they are invoked they are called as closures in a new environment, not in the lexical environment where they are defined.

CPU exceptions are like this. When an exception happens (page fault, division by zero, privileged instruction, ...) a snapshot of the machine state is saved in some exception frame (and perhaps some of the work of recovering the state is up to the handler).  This allows the handler to fix up the situation and re-start the program from the very instruction that triggered the fault. For instance, make a not-present page of memory available.

C++ exception handling is just syntactic sugar for longjmp. It is not exception handling, it is exception bailing with cleanup, which is just a notch better than bailing without cleanup.

Name: Anonymous 2012-01-28 21:43

>>15

Assertions are for internal errors. Errors in general are exceptional situations that can arise in the normal operation of a correct program.

Do you think you can just assert that you have enough memory? Or that you have the privileges to access something? Or that you're properly configured? Etc.

Name: Anonymous 2012-01-28 22:08

>>17

Do you think you can just assert that you have enough memory?

If I have complete control over the memory pool (it's already allocated in a buffer), and I can prove that my program will never exceed the requirements, then yes, I will assert and not bother with checks in the final version. If the amount of memory used depends on something like user input, or if the memory allocation operation goes through the operating system, then I don't have enough information to prove that enough memory will be available, so the case of not getting it must be handled.

Or that you have the privileges to access something?

I don't know what the operating system will do, so no. My program cannot control what the operating system will tell it, so that information has to be checked and handled in some way, even if it is just a message to the user saying it can't run for reason X.

Or that you're properly configured?

If the configuration was hard coded in at compile time, then I am tempted to say that assertions will be fine. Although a leat haxor could go into the binary and locate the constants and change them. But then the leat haxor could modify other things, like replacing the checks on the configuration with nops. If the user has some influence on the configuration file, then the values must be checked when the file is loaded. But once the file is loaded and verified to be correct, no more checks are needed, and assertions can be used where the stats are referenced. If no one but the developers are assumed to access the file, then assertions are appropriate for the loading phase.

Name: Anonymous 2012-01-28 22:29

>>16

yeah, one way to get better exception handling in seeples is to create an error handler interface and have various implementation of it, and then you can pass instances of the error handlers down the stack by putting references to them in argument lists. Then when the exceptional situation occurs, the function can call a method in the error handler interface, giving information about the exception to the error handler through the parameter list of its method. And if you find that the error cannot be recovered from like that, then the error handler method can throw a normal seeples exception, and it can be caught somewhere down the stack.

Name: Anonymous 2012-01-28 22:31

>>19

This would be a bit easier in java due to anonymous classes. It could start looking more like the try catch syntax by embedding the definition of the error handler into the function that would normally contain the try cache block.

Name: Anonymous 2012-01-28 23:01

>>20
No. Uhhhh......No.

Name: Anonymous 2012-01-28 23:10

>>21
y u no leik anonymouse classes?

Don't change these.
Name: Email:
Entire Thread Thread List