6 ms·
Same here. I have a theory. The obscure error are due to unexpected Syscall results. Programmers are very aware of the states their programs can be into given t
by ptsneves 3y ago
Same here. I have a theory. The obscure error are due to unexpected Syscall results. Programmers are very aware of the states their programs can be into given the visible logic. They often are not aware of the possible states a syscall can be and their error modes.
A pattern I see in python programs is the sys.exit and exception avoidance because they don’t want the user to see a stack trace. So they rely on conditionals and sys.exits, never considering and catching the exceptions that things like open and write can raise, leading ton exception traces anyway. This is one of the reasons strace sometimes is required. I have seen experienced programmers doing this pattern again and again and they are really convinced that it is helpful and consistent. This highlights the what I wrote above programmers often ignore the way external dependencies work, in this case the syscalls.
Another common syscall related issue strace helps is with permissions denied. Most scripts just defend against the file existing and not whether the operation is possible, leading to obscure messages like operation not permitted. Strace to the rescue in such cases
It is one oft first lines of debugging, even if I have the source code, as sometimes the syscall that fails is buried deep in library code, but with the failed syscall and arguments I can track the line that made the wrong call.
- cwillu 3y ago> I have seen experienced programmers doing this pattern again and again and they are really convinced that it is helpful and consistent. In a nutshell, this is why I hate working in go. While I'm sure your code, dear hn golang fan, doesn't suffer from this, much of the go code I've had to deal with extends the principle of “unaware of many common failure modes and swallow them into the exit code” to every function.
- angra_mainyu 3y agothat's strange, I've been working professionally in Go for years and two things happen: 1) what are exceptions in many languages are plain errors in Go 2) a defer-recover block is usually put at the very top of a risky call This covers 99% of sources of panics. Now, the one that truly does mess you up is when it comes from CGO/calling out to C. That will tear your application and there is nothing you can do about it.
- cwillu 3y agoI wish they paniced. I'm talking about trees of function calls with variations on “err = thing(); if err: return err” multiple times in a function, so receiving an error code in the root function tells you very little about what went wrong or where it went wrong.
- gpderetta 3y agoExactly! Throwing away the call stack before deciding how to handle the error is not ideal.
- angra_mainyu 3y agoI've honestly never needed it when dealing an error, the fact that errors are handled near where they occur means a stack is rarely needed. If you bubble up errors a lot then errors.Is/As is made for that purpose. You really only care about a stack trace with a panic. In anycase, runtime.Stack() iirc should return the stack. But this sounds more like trying to write other languages in Go rather than writing in Go.
- sgarland 3y agoThis is why for my Python programs, while I swallow exceptions when possible and turn them into user-friendly error messages that are likely to be the cause, I also add a -d,—-debug flag that ignores that and spits out everything. Because when you need to know, you need to know.
- digitalsushi 3y agoPeople who need to be doing other things with their lives utter silent prayers of gratitude when they hope your code that does that exists, and does
- lelanthran 3y ago> Most scripts just defend against the file existing To me, any code calling a `DoesFileExist(filename)` type of function is a code smell. There is no point to checking if the file exists. None. Ever![1] There is never a case where this is useful. The only times I see code that checks for the existence of a file is when, on subsequent lines, the file is used as if it exists (no error-checking on open), which is a bug. A line in code that checks for the existence of a file correlates, in my experience, very strongly with using that particular file in that specific buggy manner. [1] You might say that it's to provide a better user experience, such as "Your config file does not exist, do you want to create it?" or similar, but that's still buggy if you're determining whether the file exists by checking existence.
- overbytecode 3y agoOkay..what is the alternative?
- lelanthran 3y ago> Okay..what is the alternative? Just ... open the file and handle the error? What are you getting by checking that the file exists that you don't get from the 'file not found' error that the `openFile()` routine returns? Because it doesn't matter if `doesFileExist()` returns true, you still have to handle the `file not found` error[1] when calling `openFile()` on the next line anyway. [1] Just because the file exists when the program checked, that doesn't mean that the program can open it (permissions), that the file still exists (could have been removed between the call to check and the call to open), that the file is, in fact, a file that can be opened (and not a directory, for example), that the file is not exclusively locked (Windows) by some other process that opened it, etc. `doesFileExist()` tells you nothing that would change how the subsequent is written.
- pixl97 3y agoAnd if it's the initial configuration file?