6 ms·
> One of the things Go taught me is that I was not being as careful about my errors as I should be. I identify with this so much. Especially when dealing with
by vlunkr 5y ago
> One of the things Go taught me is that I was not being as careful about my errors as I should be.
I identify with this so much. Especially when dealing with external things (file system, database, network) things can go wrong at nearly every step. And yeah, that means you have to check errors at every step, but it forces you to think about how you want to handle them, and what message you want to propagate when they happen. As a result, my Go code has very few unexpected errors in production.
- new_stranger 5y agoHard to overemphasize this. Handling errors is similar to the benefits that writing tests provides - slower upfront, but a more stable product gets shipped. Handling errors everywhere means problems are already solved before they happen. No 1 am pagerduty alerts because we didn't consider what would happen if a DNS server hung until we timed out and thought just wrapping in a try/catch and crashing was a good idea.
- closeparen 5y agoThings can go wrong at every step, which means each collection of fallible steps carries with it a combinatorial explosion of successes and failures. Do 5 fallible statements in sequence and it's 5+4+3+2+1 = 15 mock expectations you need to write. This tedious enumeration exercise is the majority of the time that goes into writing Go programs, for me at least.
- boloust 5y agoMost of the time, you'll return early after an error. To get into a situation where you'd need to handle n! cases, you'd need to keep running the statements after a failure, and then collate and return all the errors at the end. Not sure why you'd want to do that. You'd definitely need to go out of your way to do something like this, and probably start asking yourself why you're doing this pretty early on. Plus it would flat out refuse to compile in some cases where there are dependencies between the statements.
- closeparen 5y agoIt’s + not * in that example.
- boloust 5y agoAh, okay. In that case it becomes {n + 1 \choose n - 1} What code are you writing that results in this set of possibilities?
- jerf 5y agoI have some code where I use multierrors and collect everything into one big error (I highly recommend this for "validation"-type code, you should generally return all errors not merely the first), but what code are you writing where you're running 5 statements unconditionally but need to handle nearly-arbitrary combinations of them failing, and multierrors aren't what you need?
- closeparen 5y agoIf you have 5 statements like "if err := doThing(); err != nil { return err }" then you need to simulate the success of all 5, success of the first 4 and failure of the last, success of the first 3 and failure of the 4th, success of the first 2 and failure of the 3rd, etc.
- morelisp 5y agoFor a total of six cases to deal with. Not 15.
- closeparen 5y agoI said 15 mock expectations, not cases.
- morelisp 5y agoIf all five of those things also need to be independently mocked, you're mocking too much and your mocks suck.
- closeparen 5y agoIf they're not mocked it's an integration test. Integration tests are welcome as a supplement to unit tests, but unit tests are table stakes.
- morelisp 5y ago