Throwing exceptions and error handling

Angel Ortiz
Angel Ortiz

Some people like throwing exceptions all over the place, putting try and catch blocks on anything they can (such as args parsing, etc), and generally making a mess of things. I find that introductory programming courses really encourage this kind of behavior because they are required to have a section that teaches about exceptions.
Some people say that you should almost never throw exceptions, unless the problem truly is exceptional. This makes a lot more sense to me.
However, recently I learned that people are putting exceptions into their constructors because we're all being forced to use shitty languages that have no other way to return a failure from a constructor or to check the constructor's inputs. Is this really the solution (for langs such as c++)?
What do you think?

Other urls found in this thread:

mail.python.org/pipermail/python-3000/2007-July/008663.html
rosettacode.org/wiki/Echo_server#Erlang
rosettacode.org/wiki/Hello_world/Web_server
rosettacode.org/wiki/Chat_server#Erlang
python.org/dev/peps/pep-3136/
doc.rust-lang.org/book/first-edition/error-handling.html#the-option-type

Ethan Allen
Ethan Allen

I only use asserts, and have literally never used exceptions. I work on games, where exceptions are discouraged and pretty much never used at all.

William Edwards
William Edwards

C++ projects that avoid exceptions do empty constructors that require an initialize() call. I don't think it's worth avoiding them today as almost all platforms now produce mostly sane code for them, although there are still some horror shows. They should only be used to handle unexpected errors though, as they're still a complex, bloaty, and awkward form of feedback. E.g. if you're writing a network transport and your "buffer full" feedback is an exception then you've fucked up.
shitty gamedev error 'handling'
gamedevs really shouldn't be in these conversations.

Cameron Morgan
Cameron Morgan

error checking is for the weak
you either write bad ass code in one pass
or you go home

Ayden Lewis
Ayden Lewis

Also, I'd suggest networking as the trial by fire for error checking. Try writing some non-trivial low-level networking code in Linux to get a feel for how your method of error handling works. My C code is almost always more than 50% error handling. If you want to get that closer to 100%, try using anything where you need to work with CMSG headers.

Ryan Scott
Ryan Scott

If a function can fail, you just make it return something indicating it failed, such as -1, false, 0, None, Nothing, or even writing to an output variable if the language forces you to. Exceptions are some retarded shit for the same group who think the precanned HTTP methods and error codes have any point.

Fun fact: 50% of the code in existence which relies on exception handling will just fail and show the exception to the user, leaving the code still broken because the exception wasn't properly handled. The other 50% will just fail, be ignored by a top level handler, and not tell the user anything, _still_ leaving the program in a broken state.

While you _can_ use exceptions properly, it just ends up being a roundabout way of having "exceptional" return values.

Ethan Gomez
Ethan Gomez

They should only be used to handle unexpected errors though
If you write the code to handle it, doesn't that mean it's expected?

Christopher Clark
Christopher Clark

Think of a web browser. Getting a 404 is an expected error, and handling it out of band would just complicate the code.

Xavier Morgan
Xavier Morgan

He's just being a smartass I hope. If not then there are Amish people with more understanding of tech than him. Wouldn't surprise me given the scummy neo luddites that show up here sometimes.

Luis Morris
Luis Morris

I'm guessing exceptions are not the same as errors. However I can't really think of an example where an exception isn't an error.

William Myers
William Myers

exceptions aren't just for error handling
this is how you break loops in python

class LoopBreak(Exception):
pass

b=3
try:
while(1==1):
for i in range(0,10):
if i==b:
raise LoopBreak
except LoopBreak:
print("i=b")

Isaiah Wright
Isaiah Wright

Actually, exceptions are an elegant way of handling what can be incredibly obtuse chains of failures in real-world software. The only real argument for not using them is in the case of absolute time/space determinism needs (as in realtime application areas).

And as far as C++ is concerned, the language will let you write as much error code spaghetti return code as you'd care to though you'd be ignorant to say the least to use that approach when RAII is so beautiful mathematically.

Asher Bennett
Asher Bennett

That's horrific and must be outrageously expensive. Just use a variable like someone who isn't deliberately trying to be the biggest faggot in the world.

Ryan Taylor
Ryan Taylor

I think the sole purpose of the post is provoking hostile reaction.

Luke Nelson
Luke Nelson

user, I'd like to introduce you to my friend; his name is break.

John Peterson
John Peterson

He's trying to work around python not having a multi-level break, and instead of just adding a variable like anyone sane is using a massive amount of bloat and a custom class.

Carson Long
Carson Long

breaks don't break out of multiple layers of loop
this

Lincoln Allen
Lincoln Allen

it's not just a workaround i'm pretty sure this is the suggested "pythonic" way to do multilevel break in python. i'm not suggesting it's good, but it's python.

Cameron Perry
Cameron Perry

loop1:
#do some shit
loop2:
#do some more shit
break
break
#even more shit

Zachary Hall
Zachary Hall

No well-run python project would allow someone to commit that.

Luke Bell
Luke Bell

The inner loop needs to set a flag as the second break is conditional.

Brandon Ross
Brandon Ross

I like Erlang, "Let it crash", way of error handling. Basically processes are organized in the hierarchical order within process tree. If something unexpected happens you just restart sub-tree and start from clean state.
It is a lot easier than trying to enumerate all the errors. And it is a lot safer to start from clean state than trying to fix state when error is detected.

Joshua Peterson
Joshua Peterson

The pythonic way is to do it with

def execute():
shellcode = bytearray("\x31\xC9\xB8\x02\x00\x00\x00\x31\xDB\x39\xD8\x7E\x03\x43\xEB\xF9\x01\xD8\x41\x83\xF9\x05\x75\xF1")

Christopher Evans
Christopher Evans

I work on games, where exceptions are discouraged and pretty much never used at all.
So (You) are the reason why when games crash, they crash with either Unhandled Exception or Segmentation Fault. Let me guess, you also use asserts to check if the pointers are not null?

In my experience, albeit limited, there's very little that you can do after catching the exception, other than CLE: 1) clean up, 2) log and 3) exit.

To me an exception represents an unfixable error: data is corrupted, data can't be read, data can't be written, file can't be opened, memory can't be allocated, this sort of thing. The kind of thing which is a fatal error because it doesn't make sense to retry doing it once it failed. So basically, a user inputting the wrong password is not an exception, but not being able to open the password hash file is. If I'm wrong teach me.

Michael Brooks
Michael Brooks

The only use case for goto. This and meta generated automatons.

Ian Nguyen
Ian Nguyen

goto is also very useful for error handling.

Brandon Ortiz
Brandon Ortiz

lemme guess you'd like the game to crash with Handled Exception.

Ryder Nguyen
Ryder Nguyen

No, I'd like it to crash with a proper error message, you little faggoteer.

Thomas Davis
Thomas Davis

looks like this bear ass isn't collectible, better crash the player's game without saving rather than handle the error

Aiden Richardson
Aiden Richardson

In games it is unimportant, wow the game crashed after 16 hours of gameplay, too bad, just restart the game faggot, big deal.
If you have to constantly catch exceptions, your code is shit. Better discover your programming errors with asserts during development, and fix them immediately, than having to do run-time damage control with slow ass exception handling.

Zachary White
Zachary White

Python uses exceptions internally all over the place. They're relatively inexpensive, taking the efficiency of the rest of the language into account.
For example, StopIteration.

Matthew Collins
Matthew Collins

If you didn't have while loops then implementing a while loop using goto would also be a use case. I can't help but feel that use of goto is a symptom of a missing feature.

Gavin Young
Gavin Young

just restart the game faggot, big deal
If you have to constantly catch exceptions, your code is shit.
gamedevs, everyone.

Aiden Gutierrez
Aiden Gutierrez

They're extremely expensive. Don't make me rub your nose in this.

Matthew Green
Matthew Green

this tbh. the language is such shit that worrying about exception costs is like worrying that you tracked a little bit of dirt into the pigsty.

Robert Miller
Robert Miller

I said "relatively". Python exceptions in particular are not that bad compared to all the other things in Python, which also tend to be slow.

Jayden King
Jayden King

Exceptions are fantastic. You don't have to think of every edge case when you can just handle a blanket exception and log something about it.

You can also avoid messy if/else if/ else blocks or switch statements if you replace it with the code that covers the intended case in a try block.

Tyler Hill
Tyler Hill

Games run fast. Even terrible 30fps games are way way faster than pretty much everything else you use.
But hey at least all the other software never crashes due to all their error handling right.

Daniel James
Daniel James

It's a big "relatively". They're super heavy. Even in that simple example earlier where most of the time is spent printing, they're still heavy enough to double the runtime.


#!/usr/bin/python

class LoopBreak(Exception):
pass

def foo1():
b=3
try:
while(1==1):
for i in range(0,10):
if i==b:
raise LoopBreak
except LoopBreak:
print("i=b")

def foo2():
b=3
done = False
while(1==1):
for i in range(0,10):
if i==b:
done = True
break
if done:
break
print("i=b")

for i in xrange(1000000):
#asdf
#foo1()
#foo2()


$ time ./foo.py > /dev/null

real 0m1.855s
user 0m1.843s
sys 0m0.015s

$ time ./foo.py > /dev/null

real 0m0.950s
user 0m0.937s
sys 0m0.015s

Connor Taylor
Connor Taylor

Games run fast. Even terrible 30fps games are way way faster than pretty much everything else you use.
lol. I do low-level networking and I can guarantee you that 99% of gamedevs can't even figure out how to properly handle affinity let alone do anything that needs to be fast. It's funny to real programmers as gamedevs don't realize they're looked at like webdevs with egos.

Oliver Butler
Oliver Butler

real programmers
truly embarrassing

Asher Morales
Asher Morales

What's the best language for network shit?
inb4 rust

Oliver Turner
Oliver Turner

goto fail

Brayden Johnson
Brayden Johnson

how to properly handle affinity
not him, but what is this?

Jonathan Hill
Jonathan Hill

What user really meant to say was, how to properly handle "furaffinity".
Do i need to say more?

Isaiah Wood
Isaiah Wood

mail.python.org/pipermail/python-3000/2007-July/008663.html
lmao what a fag

Wyatt Cooper
Wyatt Cooper

Probably Erlang to be honest, it provides very clean abstractions for such tasks.

rosettacode.org/wiki/Echo_server#Erlang
rosettacode.org/wiki/Hello_world/Web_server
rosettacode.org/wiki/Chat_server#Erlang

Jayden Gomez
Jayden Gomez

What is the best language that is actually being used?
FP is a meme user

Jason Miller
Jason Miller

You want to tell your operating system to schedule a program on the same core/s each time to reduce cache misses. Setting this is usually refered to as setting a programs "affinity".

Most people don't need to care since computing power is a dime a ghz. Sometimes if you're running on resource constrained systems you need to care.

Oliver Roberts
Oliver Roberts

no shit, what a turd, so this actually is the correct way to do it in python.
python.org/dev/peps/pep-3136/
and they're never going to change it.
code that requires breaking out of more than 1 loop is "complex". and god forbid they add the functionality and programmers do shit with it they don't like and can't read.

that pep states all the alternatives that I can think of, all of them shitty.
1 - use a variable for each layer of loop and end up with a mess of variables and checking to break each loop
2 - Break exception
(1 and 2)
3 - basically 1 but using more if statements at the end instead of checking a variable.

The loop break exception, 2, makes a lot more sense to me but fuck, that 100% performance hit. Option 3 has to perform worse by definition than 1 because it's just multiple if statements instead of the one if statement for the variable.

I'm glad I got used to straight C again.

Tyler Evans
Tyler Evans

FP can be a meme, and it's certainly not something your average JS/Java dev is going to care about, but there are companies out there writing solutions in Erlang.

Racket is also quite nice to write servers in, but as you said actually used, I assume you mean popular. None of the popular languages really add much to sockets over what C is doing, although Go has features which remove the complexity of multithreading.

If I had to write a server right now, I'd choose in order of preference: Erlang, Ada, Racket and C. If I thought it might be maintained by others, then Go would be a good choice.

tl;dr Use Go.

Justin Ramirez
Justin Ramirez

nice try google shill

Joshua Jones
Joshua Jones

C and C++. I'd strongly recommend C-like C++ as exception handling drastically reduces the ridiculous amount of error handling.

Joseph Ward
Joseph Ward

exception handling drastically reduces the ridiculous amount of error handling.
explain further

Dominic Rivera
Dominic Rivera

Use of RAII and exceptions means in most cases you can just skip adding any error handling. You also don't need to write error forwarding either (call function, returns -1, check if it returned -1, return -1, etc..).

Nicholas Bailey
Nicholas Bailey

use RAII + exceptions == no error handling code needed
pajeetgod tier error handling:
int main()
try
{
}
catch (...)
{
std::clog << "Sorry!\n";
}

let's hope the global object constructors don't throw, because I dunno how to catch those.

Cameron Reyes
Cameron Reyes

have to work with java for CC uni
as if the language wasn't shit by itself, every fucking library throws exceptions
I fucking hate this shit. I can't just validate input on a higher layer and send it down on the basis that it's going to work, the language assumes you're a retard and everything is going to break if they let you handle basic shit though I guess that's true, for most >java programmers, at least.
Why can't they just make functions that return null if shit fucks up instead of forcing you to use try catchs or throwing shit?

Jonathan Powell
Jonathan Powell

Imagine break and continue statements taking a loop top-level argument (break(2) break out of two loops, for example). This would be pretty good.

Ryder Smith
Ryder Smith

even better:
fn main() {
let arg = std::panic::catch_unwind(|| std::env::args().nth(1).unwrap().parse::<i32>().unwrap());
println!("{:?}", arg);
}

Dominic Edwards
Dominic Edwards

How do exceptions give you less freedom to handle shit than null return values?

Jose Thompson
Jose Thompson

With exceptions, you have to treat them, or else it might not even compile, whereas you can do whatever you want with nulls.

I can't think of anything right now, but let's say you have something in your program that may not run in some computers. It's just a fancy cool thing you want to run, but there's no detriment in not running it, the user doesn't even need to know that it didn't work. Maybe it's a bug regarding hardware or just some OS stuff.
Anyway, with null returns you can just call the function. Done. You don't need to know if it ran or not.
With exceptions, however, you need to treat it, no discussion. So you end up with an useless try catch in the middle of your code that serves no purpose.

Another case where null values are better is like the above, where you won't treat it, except in this case you already know it's not going to generate errors.
Your program does something like, for example, opening a file, except you have a front end for the user that makes sure the file exists.Maybe your program scan for files and only lets the user select from those, in any case, it won't try to open an invalid file.
With nulls, you just call the function and open the file. Done.
With exceptions, however, you, once again, need to either have an useless try catch, or just throw everything for as long as you can. It both clutters your code and it's simply unnecessary.

Plus, if you are doing many things at once, you might need to nest try and catches, which looks fucking disgusting.

Mason Morris
Mason Morris

let's hope the global object constructors don't throw, because I dunno how to catch those.
Like this: struct muh_type
{
muh_type() { throw 0; }
};
muh_type muh_object = []{
try { return muh_type(); }
catch (...) { std::cerr << "muh exception handling"; /* ... */ }
}();

James Powell
James Powell

Funny how Rust solves all the constructor problems by going back to the old way.
In Rust, "constructors" are just a convention:
impl<T> Vec<T> {
pub fn new() -> Vec<T> { ... }
}

Constructors are static (no self) inherent methods for the type that they construct. Combined with the practice of fully importing type names, this convention leads to informative but concise construction:
use vec::Vec;
// construct a new vector
let mut v = Vec::new();

There is exactly one way to create an instance of a user-defined type: name it, and initialize all its fields at once:
struct Foo {
a: u8,
b: u32,
c: bool,
}

enum Bar {
X(u32),
Y(bool),
}

struct Unit;

let foo = Foo { a: 0, b: 1, c: false };
let bar = Bar::X(0);
let empty = Unit;

That's it. Every other way you make an instance of a type is just calling a totally vanilla function that does some stuff and eventually bottoms out to The One True Constructor.
Unlike C++, Rust does not come with a slew of built-in kinds of constructor. There are no Copy, Default, Assignment, Move, or whatever constructors. The reasons for this are varied, but it largely boils down to Rust's philosophy of being explicit.

Constructors were a mistake. Exceptions were a mistake. Rust uses the Option enum for returning errors.
doc.rust-lang.org/book/first-edition/error-handling.html#the-option-type

Kevin Carter
Kevin Carter

You don't understand, but then that's expected. With RAII and exceptions, you don't need error handling and forwarding on calls where you weren't doing error recovery. The exact same error response as you might have written in C can thus be coded with a tiny fraction of the error handling code, which is good as error handling code tends to be extremely poorly tested and buggy.

Jaxon Wood
Jaxon Wood

let mut v = Vec::new(); Somehow this is supposed to be better than Vec v;lol rust.
You can do the same static pseudo-constructor thing in C++ if you really want to, by the way.
Rust's philosophy of being tedious and ugly
fixed
Rust uses the Option enum for returning errors.
le .unwrap() syntax noise face

Jace Russell
Jace Russell

That's disgusting even for C++, congrats!

I have a question though, what if the move constructor throws? Or is it the copy constructor, I'm not 100% sure. Please don't tell me about noexcept because I'm not in the mood for std::terminate.

Daniel Allen
Daniel Allen

That's disgusting even for C++, congrats!
Is straightforward simplicity and an absence of dumb syntax noise considered "disgusting" by the rust community? Is rust the cause of mental illness, or do you have to be mentally ill to like rust?
if the move constructor throws
If you build your shit right, there's no reason it should be able to.
Or is it the copy constructor
You catch the exception and deal with it. Or you don't, and let the program terminate. There is nothing special about the copy constructor in that regard.

Gavin Johnson
Gavin Johnson

Constructors aren't mandatory in Rust, did you even fucking read the post?

Angel Rivera
Angel Rivera

goto-oriented programming is considered pythonic
No wonder the productive half of their ecosystem avoids the python 3 half like aids

Gavin Reed
Gavin Reed

1337 skiddie tryhards like you are the reason metrosexuals like EA now own the game industry

Thomas Perez
Thomas Perez

Constructors aren't mandatory in Rust
Where did I imply that they are? Did you fucking read my post? I was comparing C++ constructors with whatever rust has that has the same capabilities and general semantics. Comparing constructors with plain named initialization (which C also has and C++20 will have) is like comparing apples to oranges.

Nicholas Barnes
Nicholas Barnes

Just to mention, in (when you remove the throw statement) neither the copy constructor nor the move constructor is ever called, thanks to guaranteed copy elision (since C++17). It's truly zero overhead. And if you want to limit the boilerplate, just declare all your global variables as fields of a struct with default values, then instantiate that struct and do the try-catch thing just once. Normally you shouldn't have that many global variables anyways.

Ethan Flores
Ethan Flores

These names are hilarious.

Ayden Walker
Ayden Walker

EAFP is literal trash that leads to nothing but legitimate errors being silenced, I avoid it as much as possible (except for things like writing to files where I need to check the writes gone through etc).

Hudson Cruz
Hudson Cruz

asserts are for when you get to an internal state in your own code that you didn't expect. An assert should never get triggered and if it does it implies you should fix something in your code.

Exceptions (or equivalent logic to propagate errors to the caller) are for a state caused by something external to your code, but that you cannot handle. An example is the environment, where if a file is missing we might be able to propagate that error up to a level where we could tell the user about it. Similarly if they are not connected to a network. Another example is bad input to a library. As the library author you can't guarantee that the user gives you valid input so you need exceptions to tell the user about this.

As a game dev, it makes sense that you don't use exceptions because you are writing a single monolithic product, not a library.

Angel Bailey
Angel Bailey

*game server shits itself*

better not provide contingency plan for this on client

Caleb Jenkins
Caleb Jenkins

I only put try/catch statements to handle the programming language's own exception throws.

Jack Foster
Jack Foster

You could make an anonymous function and use "return" to get out of all the loops.