New around here? Register your SA Forums Account here!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Powerful Two-Hander
Mar 9, 2004

Mods please change my name to "Tooter Skeleton" TIA.


jfc I am a moron because I just spent about 4 hours trying to deserialise xml generated from a set of interface implementations to concrete objects because xmlreader is a pile of poo poo and I'm terrible. I literally wasted an hour trying to work out what a cryptic error was that turned out to be "because you read the innerxml to debug, the reader advanced and is now empty but instead of telling you you're reading an empty node it'll just barf some cryptic poo poo about 'element is not an element" "

pretty sure I should have used a different approach (linq to xml maybe) and then cast to a reader later for the nested interface objects but I got hung up on it and ended up just doing trial and error.

Also get hosed whoever thought that it was a good idea to force you to code to explicitly ignore the element closure for <butt/> instead of having endelement just do nothing if it's self closing

Adbot
ADBOT LOVES YOU

gonadic io
Feb 16, 2011

>>=

Powerful Two-Hander posted:

I literally wasted an hour trying to work out what a cryptic error was that turned out to be "because you read the innerxml to debug, the reader advanced and is now empty but instead of telling you you're reading an empty node it'll just barf some cryptic poo poo about 'element is not an element" "

i've done this before too (but with http4s (or play?) entity streams

hey you have a problem so you add a debug statement to log out the stream contents
now you have 2 problems and haven't even noticed

Mao Zedong Thot
Oct 16, 2008


Finster Dexter posted:

ctps: golang. jfc I wish this lang had real error handling. I can only handle expected errors and if you have an unexpected error somewhere lmao good luck, and may all your panics not be silently recovered somewhere else.

panics are exceptional, dont use them unless u want to crash

MononcQc
May 29, 2007

the entire idiocy of go's error handling is not that you need to check the return values here and there; monad and maybe types have you do that in Haskell or Rust all the time, so do Erlang and Elixir's tuples.

The stupid part of it is that go will not be mad if you don't check them and will happily keep on trucking into undefined program behaviour and do whatever it can without bailing out. Then the goroutine may vanish, but it will do so silently and undetectably for the most part, so you're stuck with a bunch of partly-failed and leaked goroutines with possibly busted memory, but from the outside, the little binary looks like it's doing fantastic

Shaggar
Apr 26, 2006

Powerful Two-Hander posted:

jfc I am a moron because I just spent about 4 hours trying to deserialise xml generated from a set of interface implementations to concrete objects because xmlreader is a pile of poo poo and I'm terrible. I literally wasted an hour trying to work out what a cryptic error was that turned out to be "because you read the innerxml to debug, the reader advanced and is now empty but instead of telling you you're reading an empty node it'll just barf some cryptic poo poo about 'element is not an element" "

pretty sure I should have used a different approach (linq to xml maybe) and then cast to a reader later for the nested interface objects but I got hung up on it and ended up just doing trial and error.

Also get hosed whoever thought that it was a good idea to force you to code to explicitly ignore the element closure for <butt/> instead of having endelement just do nothing if it's self closing

you should be using xmlserializer to serialize and deserialize directly to types. XDocument is better if you actually need direct xml touching

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder

MononcQc posted:

the entire idiocy of go's error handling is not that you need to check the return values here and there; monad and maybe types have you do that in Haskell or Rust all the time, so do Erlang and Elixir's tuples.

The stupid part of it is that go will not be mad if you don't check them and will happily keep on trucking into undefined program behaviour and do whatever it can without bailing out. Then the goroutine may vanish, but it will do so silently and undetectably for the most part, so you're stuck with a bunch of partly-failed and leaked goroutines with possibly busted memory, but from the outside, the little binary looks like it's doing fantastic

I agree, the problem is not with the semantics of go's error handling. returning errors as values is good, in my experience.

go just does nothing to make dealing with errors-as-values nice, so it sucks.

gonadic io
Feb 16, 2011

>>=

MALE SHOEGAZE posted:

I agree, the problem is not with the semantics of go's error handling. returning errors as values is good, in my experience.

go just does nothing to make dealing with errors-as-values nice, so it sucks.

you see when i was a child, i liked errors-as-values...

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

MononcQc posted:

the entire idiocy of go's error handling is not that you need to check the return values here and there; monad and maybe types have you do that in Haskell or Rust all the time, so do Erlang and Elixir's tuples.

The stupid part of it is that go will not be mad if you don't check them and will happily keep on trucking into undefined program behaviour and do whatever it can without bailing out. Then the goroutine may vanish, but it will do so silently and undetectably for the most part, so you're stuck with a bunch of partly-failed and leaked goroutines with possibly busted memory, but from the outside, the little binary looks like it's doing fantastic

in theory they wrote the syntax real simple and provided good tools for writing static analysis passes to catch "ignored error returned from function"

now does anyone use those linting static analyses? yes, probably inside goog

MononcQc
May 29, 2007

MALE SHOEGAZE posted:

I agree, the problem is not with the semantics of go's error handling. returning errors as values is good, in my experience.

go just does nothing to make dealing with errors-as-values nice, so it sucks.

Returning errors as value is good, but you have to have a good uniform way to unambiguously be able to get contextual information from the origin of the error as a more remote observer. A lot of "return errors as values" does a very good job at efficiently isolating and letting you handle a bad condition locally, but do a terrible job at carrying the right context when local action is hard to take.

Imagine a routine handling 15,000 different files and that returns a thing with 'Error(enoent)' or 'Error(eperm)' rather than actual good context. Now you have no great way to gain insights about what went wrong unless you go and reconstruct the context around the failure by hand and investigation. You have to figure out the environment at the time, the possible areas of code that could have carried that information, and so on.

This brings you to the same step as Prolog returning 'false' without having an explanation as to why, something people have hated about Prolog for decades.

Invariably, better error handling has the programmer manually assemble context and carry it around, and either you need to know ahead of time what callers outside of your realm will need in terms of information, or you end up grabbing most of what you can and you end up with manually assembling stacktraces together, and now you're not that much better than if you had checked exceptions but with a more terse construct in most cases, except that you need the entire community to agree on the format that makes sense to track.

Go can't even do the latter because lol generics.

Powerful Two-Hander
Mar 9, 2004

Mods please change my name to "Tooter Skeleton" TIA.


Shaggar posted:

you should be using xmlserializer to serialize and deserialize directly to types. XDocument is better if you actually need direct xml touching

yeah but instead of diving into the poo poo pile of the xml reader I probably could have used the lonq methods to get the wrapper properties then used a reader to bind the interface objects because they're under a specific node. instead I went full dumbass and wrote a pile of lovely hand nested crap using the reader only.

Shaggar
Apr 26, 2006
smdh

Finster Dexter
Oct 20, 2014

Beyond is Finster's mad vision of Earth transformed.

comedyblissoption posted:

i hate golang as much as anyone but dont they have some type of panic and recovery mechanism for goroutines?

now, you might have to copy paste a shitload of boilerplate across every single goroutine to actually handle panics within a process, but the capability seems there?

https://golangbot.com/panic-and-recover/

Yeah and I panic and recover all over the place... but panic/recover is only helpful for expected errors, i.e. I call a function and it returns a tuple of the thing I want plus an error. The problem is (like in my case from earlier today) where I have something like "index out of range" where it's an unexpected run-time error.

Finster Dexter
Oct 20, 2014

Beyond is Finster's mad vision of Earth transformed.

MononcQc posted:

Returning errors as value is good, but you have to have a good uniform way to unambiguously be able to get contextual information from the origin of the error as a more remote observer. A lot of "return errors as values" does a very good job at efficiently isolating and letting you handle a bad condition locally, but do a terrible job at carrying the right context when local action is hard to take.

Imagine a routine handling 15,000 different files and that returns a thing with 'Error(enoent)' or 'Error(eperm)' rather than actual good context. Now you have no great way to gain insights about what went wrong unless you go and reconstruct the context around the failure by hand and investigation. You have to figure out the environment at the time, the possible areas of code that could have carried that information, and so on.

This brings you to the same step as Prolog returning 'false' without having an explanation as to why, something people have hated about Prolog for decades.

Invariably, better error handling has the programmer manually assemble context and carry it around, and either you need to know ahead of time what callers outside of your realm will need in terms of information, or you end up grabbing most of what you can and you end up with manually assembling stacktraces together, and now you're not that much better than if you had checked exceptions but with a more terse construct in most cases, except that you need the entire community to agree on the format that makes sense to track.

Go can't even do the latter because lol generics.

Oh geez didn't even know there was a whole page over here... but yeah this is exactly the problem. I wouldn't mind Go so much if it weren't for the lovely error handling.

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder

MononcQc posted:

Returning errors as value is good, but you have to have a good uniform way to unambiguously be able to get contextual information from the origin of the error as a more remote observer. A lot of "return errors as values" does a very good job at efficiently isolating and letting you handle a bad condition locally, but do a terrible job at carrying the right context when local action is hard to take.

Imagine a routine handling 15,000 different files and that returns a thing with 'Error(enoent)' or 'Error(eperm)' rather than actual good context. Now you have no great way to gain insights about what went wrong unless you go and reconstruct the context around the failure by hand and investigation. You have to figure out the environment at the time, the possible areas of code that could have carried that information, and so on.

This brings you to the same step as Prolog returning 'false' without having an explanation as to why, something people have hated about Prolog for decades.

Invariably, better error handling has the programmer manually assemble context and carry it around, and either you need to know ahead of time what callers outside of your realm will need in terms of information, or you end up grabbing most of what you can and you end up with manually assembling stacktraces together, and now you're not that much better than if you had checked exceptions but with a more terse construct in most cases, except that you need the entire community to agree on the format that makes sense to track.

Go can't even do the latter because lol generics.

yeah this is really on point, you're a great writer.

the current vogue in rust error handling lets you add context to an error before sending it up the chain, it's really nice. i'm using it in my emulator.

Finster Dexter
Oct 20, 2014

Beyond is Finster's mad vision of Earth transformed.

MALE SHOEGAZE posted:

yeah this is really on point, you're a great writer.

the current vogue in rust error handling lets you add context to an error before sending it up the chain, it's really nice. i'm using it in my emulator.

Yeah I was looking at the error handling in rust and I'm practically salivating. Makes me wish I could convince the CTO to switch to rust, but he's really into Go.

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder
yeah it's my favorite part of the language. i think it's very awkward for newcomers, but once you're used to it it's wonderful.

prisoner of waffles
May 8, 2007

Ah! well a-day! what evil looks
Had I from old and young!
Instead of the cross, the fishmech
About my neck was hung.

MononcQc posted:

Returning errors as value is good, but you have to have a good uniform way to unambiguously be able to get contextual information from the origin of the error as a more remote observer. A lot of "return errors as values" does a very good job at efficiently isolating and letting you handle a bad condition locally, but do a terrible job at carrying the right context when local action is hard to take.

Imagine a routine handling 15,000 different files and that returns a thing with 'Error(enoent)' or 'Error(eperm)' rather than actual good context. Now you have no great way to gain insights about what went wrong unless you go and reconstruct the context around the failure by hand and investigation. You have to figure out the environment at the time, the possible areas of code that could have carried that information, and so on.

This brings you to the same step as Prolog returning 'false' without having an explanation as to why, something people have hated about Prolog for decades.

Invariably, better error handling has the programmer manually assemble context and carry it around, and either you need to know ahead of time what callers outside of your realm will need in terms of information, or you end up grabbing most of what you can and you end up with manually assembling stacktraces together, and now you're not that much better than if you had checked exceptions but with a more terse construct in most cases, except that you need the entire community to agree on the format that makes sense to track.

Go can't even do the latter because lol generics.

uh where would https://dave.cheney.net/2016/06/12/stack-traces-and-the-errors-package fit (or not fit) into your picture of the stacktraceless error value?

like, in one's own code you can auto-capture stack traces, but other people's libraries might not have stack traces or might be recording them in an incompatible format?

code:
interface HasStackTrace { ... }
tbqh it sounds like rust error handling is Strictly Better

MononcQc
May 29, 2007

prisoner of waffles posted:

uh where would https://dave.cheney.net/2016/06/12/stack-traces-and-the-errors-package fit (or not fit) into your picture of the stacktraceless error value?

like, in one's own code you can auto-capture stack traces, but other people's libraries might not have stack traces or might be recording them in an incompatible format?

code:
interface HasStackTrace { ... }

The problems there are social:
  • the error package is optional
  • the error package is not guaranteed to be unique
  • the error package must be used by everyone ubiquitously
  • the error package may not be called and there are no warnings or no constructs about it
  • it ends up relying on "jam everything you can into a string" because even what you wrap cannot unambiguously be typed in a portable manner
Rust for example solves a bunch of these by having idiomatic, language-provided mechanisms for error type composition, macros around them to make them less cumbersome (try!) and so on.

I think it's still a bit painful when it comes to annotating the exceptions (I haven't used Rust enough) since there seems to be an ongoing discussion about this and all kinds of crates that promise to make it easier. Whereas a language where you have exceptions just handles it all for you. The try! macro is the closest thing I can think of to abstracting away the "bail out until you are in a context that knows what to do with exceptional conditions" without explicitly doing it, but requires you to annotate everything that requires it for the compiler not to yell.

I don't have enough experience with it, but it really feels like a kind of way to deal with what would otherwise be checked exceptions. Like "I know this may fail, this is not the level of abstraction at which I care."

prisoner of waffles posted:

tbqh it sounds like rust error handling is Strictly Better

Go has, unambiguously, the worst error handling in a programming language since C I could think of (I don't know mumps well enough).

Powerful Two-Hander
Mar 9, 2004

Mods please change my name to "Tooter Skeleton" TIA.



if nothing else this has confirmed I'm in the right thread

gonadic io
Feb 16, 2011

>>=

MononcQc posted:

The problems there are social:
  • the error package is optional
  • the error package is not guaranteed to be unique
  • the error package must be used by everyone ubiquitously
  • the error package may not be called and there are no warnings or no constructs about it
  • it ends up relying on "jam everything you can into a string" because even what you wrap cannot unambiguously be typed in a portable manner
Rust for example solves a bunch of these by having idiomatic, language-provided mechanisms for error type composition, macros around them to make them less cumbersome (try!) and so on.

I think it's still a bit painful when it comes to annotating the exceptions (I haven't used Rust enough) since there seems to be an ongoing discussion about this and all kinds of crates that promise to make it easier. Whereas a language where you have exceptions just handles it all for you. The try! macro is the closest thing I can think of to abstracting away the "bail out until you are in a context that knows what to do with exceptional conditions" without explicitly doing it, but requires you to annotate everything that requires it for the compiler not to yell.

I don't have enough experience with it, but it really feels like a kind of way to deal with what would otherwise be checked exceptions. Like "I know this may fail, this is not the level of abstraction at which I care."


Go has, unambiguously, the worst error handling in a programming language since C I could think of (I don't know mumps well enough).

rust's error context is an opt-in package though. plain Results suffer from that same return false problem you mentioned before (and I have been bitter by it myself until i started using the 'failure' crate and calling map_err(|e| e.add_context("line 20")) to everything. imo the context/stack trace part still has a ways to go

e: poo poo i just read the second half and we agree on this. reading is hard.

gonadic io
Feb 16, 2011

>>=
poo poo i've just had a great idea. make my own version of try! that automatically annotates the error with standard stack-tracey stuff. failure has a bunch of macros but i didn't see one that did this. too bad that the ? syntax is special and you can't override it with a trait or whatever like you can with + etc

Shaggar
Apr 26, 2006
just use exceptions.

gonadic io
Feb 16, 2011

>>=

Shaggar posted:

just use exceptions.

what's a heap?

CPColin
Sep 9, 2003

Big ol' smile.
nothin' what's a heapin' with you?

redleader
Aug 18, 2005

Engage according to operational parameters

Shaggar posted:

you should be using xmlserializer to serialize and deserialize directly to types. XDocument is better if you actually need direct xml touching

counterpoint: datacontractserializer and xmldocument

redleader
Aug 18, 2005

Engage according to operational parameters
i always find .net's xml (de)serialization to be incredibly loving irritating. it normally works, kinda. until you hit one of its billion edge cases and have to randomly try stuff until you find that one combination of attributes and xml that gives you what you want. searching stack overflow is helpful less than half the time. and god help you if you want to serialize Dictionary<>s

VikingofRock
Aug 24, 2008




For what it's worth this RFC just got accepted so rust's Error trait should improve soon™.

brap
Aug 23, 2004

Grimey Drawer
does go give a compile error if you don’t bind the error return value to something? (i.e. _)

re: xml, yeah um basically you better have an accurate xsd for whatever you’re working with and generate the classes, otherwise you’re gonna just eat poo poo

Ellie Crabcakes
Jan 31, 2008

Stop emailing my boyfriend Gay Crungus

redleader posted:

counterpoint: datacontractserializer and xmldocument

counter-counterpoint: JSON

Blinkz0rz
May 27, 2001

MY CONTEMPT FOR MY OWN EMPLOYEES IS ONLY MATCHED BY MY LOVE FOR TOM BRADY'S SWEATY MAGA BALLS

brap posted:

does go give a compile error if you don’t bind the error return value to something? (i.e. _)

yes, a returned error is an explicit part of the function's signature and if a return value isn't handled the complier will yell at you

Powerful Two-Hander
Mar 9, 2004

Mods please change my name to "Tooter Skeleton" TIA.


redleader posted:

counterpoint: datacontractserializer and xmldocument

i think you have to drag in wcf for this don't you? I think I've done this before actually and you have to stick lots of [knowntype ] decoration everywhere which works but adds one more thing to do if you add a new IButt. as it stands there's one enum and a factory that you have to add to add any new implementation of the interface which is nice

redleader posted:

i always find .net's xml (de)serialization to be incredibly loving irritating. it normally works, kinda. until you hit one of its billion edge cases and have to randomly try stuff until you find that one combination of attributes and xml that gives you what you want. searching stack overflow is helpful less than half the time. and god help you if you want to serialize Dictionary<>s

accurately describes my afternoon tbh

Shaggar
Apr 26, 2006

redleader posted:

counterpoint: datacontractserializer and xmldocument

if you're stuck in .net 2.0 sure.

brap
Aug 23, 2004

Grimey Drawer
I'm amazed anyone inside goog actually writes go and that it's not just a hilarious prank on the morons that make up most of this industry

edit: why not both, I guess

redleader
Aug 18, 2005

Engage according to operational parameters

Peeny Cheez posted:

counter-counterpoint: JSON

xml good

although json.net is pretty boss actually. it usually works a lot better than the stdlib xml serialization

Shaggar
Apr 26, 2006
I haven't had problems with xml serialization in .net w/ the standard lib. XmlSerializer works really well in my experience and linq xml is good for stuff without schema.

gonadic io
Feb 16, 2011

>>=

VikingofRock posted:

For what it's worth this RFC just got accepted so rust's Error trait should improve soon™.

this looks sweet thanks

comedyblissoption
Mar 15, 2006

A guhh? A bwuhh? A lubba wubba WHAAAA???

Ask me about TND

MononcQc posted:

the entire idiocy of go's error handling is not that you need to check the return values here and there; monad and maybe types have you do that in Haskell or Rust all the time, so do Erlang and Elixir's tuples.

The stupid part of it is that go will not be mad if you don't check them and will happily keep on trucking into undefined program behaviour and do whatever it can without bailing out. Then the goroutine may vanish, but it will do so silently and undetectably for the most part, so you're stuck with a bunch of partly-failed and leaked goroutines with possibly busted memory, but from the outside, the little binary looks like it's doing fantastic
rob pike's literal unironic solution to this problem is to not do that

Slurps Mad Rips
Jan 25, 2009

There's No Guarantee

VikingofRock posted:

For what it's worth this RFC just got accepted so rust's Error trait should improve soon™.

There's also Boat's Failure crate which is neat.

(C++20 is going to have a stack trace API, so error reporting should improve there as well)

CPColin
Sep 9, 2003

Big ol' smile.
c emulator101 s:

pre:
 CPU IS OPERATIONAL
:hellyeah: Time to implement the opcodes this diagnostic code doesn't touch!

Adbot
ADBOT LOVES YOU

DONT THREAD ON ME
Oct 1, 2002

by Nyc_Tattoo
Floss Finder

CPColin posted:

c emulator101 s:

pre:
 CPU IS OPERATIONAL
:hellyeah: Time to implement the opcodes this diagnostic code doesn't touch!

nice! hope it's not like mine where i got that message in error!

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply