Martin, Certainly! I have (in https://github.com/cpmech/gosl): Total number of files = 430 Total number of lines = 73470 (NOTE: there are Go (30%), C (30%), C++ (16%), and Fortran (8%), plus Python and R files in there...)
On Tuesday, September 5, 2017 at 5:24:28 PM UTC+10, marti...@programmfabrik.de wrote: > > Dorival, > > thanks for counting your error calls, but without any other number showing > the size of your project they cannot really put in perspective ;-) > > And I think *watch* should not only be function bound, but bound to the > current scope, same as *var*. > > Martin > > > On Tuesday, September 5, 2017 at 9:20:10 AM UTC+2, Dorival Pedroso wrote: >> >> And I've written 231 error messages (I use a function called chk.Err() to >> do so): >> find . -iname "*.go" -exec grep -inH "chk.Err" {} \; | wc -l >> 231 >> >> See the messages here: >> https://gist.github.com/cpmech/d2e36dcbe277cd72605f3732d79c798b >> >> And I have a feeling that I've done only 20% of the error messages... >> (lots of work still needed...) >> >> >> On Tuesday, September 5, 2017 at 5:15:16 PM UTC+10, Dorival Pedroso wrote: >>> >>> I'm working on a Go project right now and I realised I've written 569 >>> "if err != nil": >>> find . -iname "*.go" -exec grep -inH "if err != nil" {} \; | wc -l >>> 569 >>> >>> >>> On Tuesday, September 5, 2017 at 4:57:45 PM UTC+10, Axel Wagner wrote: >>>> >>>> >>>> >>>> On Tue, Sep 5, 2017 at 8:49 AM, <marti...@programmfabrik.de> wrote: >>>> >>>>> Axel, >>>>> >>>>> thanks for the reply. >>>>> >>>>> As I already replied to Tomas, I am not looking for improvements in >>>>> this particular case where I need to call an SQL database. >>>>> >>>>> An no, I dont want to wrap all function I use into something which >>>>> collects the errors for me. >>>>> >>>>> Let's say you want to log & panic & exit after any error. >>>>> >>>>> How do you do that, without putting code after each statement or >>>>> wrapping? >>>>> >>>> >>>> You don't. But it's a bad idea. And "I want to make writing bad code >>>> easier" isn't a very convincing argument for a language-change. >>>> >>>> You can't. And that's why I am proposing to be a little bit open to new >>>>> ideas. >>>>> >>>> >>>> And how open are you to the idea that good error handling isn't about >>>> writing the least amount of code or bubbling up an error in the most >>>> efficient way, but about *handling errors*? Because you haven't really >>>> replied to that part. >>>> >>>> (and FTR, one of the points I was making is, that this isn't a new >>>> idea. It's proposed fairly frequently) >>>> >>>> >>>>> Every modern language I know of has some sort of try...catch construct. >>>>> >>>> >>>> Go is modern and doesn't have it. So this seems cherry-picked. >>>> >>>> >>>>> >>>>> >>>>> Martin >>>>> >>>>> >>>>> >>>>> >>>>> On Monday, September 4, 2017 at 10:57:51 PM UTC+2, Axel Wagner wrote: >>>>>> >>>>>> See, e.g. here >>>>>> <https://groups.google.com/d/topic/golang-nuts/ROr5jveMQvg/discussion> >>>>>> or >>>>>> here >>>>>> <https://groups.google.com/d/topic/golang-nuts/68J-mLCC1JI/discussion> >>>>>> for >>>>>> previous discussions of very similar (even mostly identical) proposals. >>>>>> >>>>>> What I always dislike about these kinds of proposals is, that they >>>>>> are encouraging not handling errors, but instead just passing them >>>>>> up-stack. In general, all of the sites where you are checking for errors >>>>>> will signify different error conditions, that should be communicated >>>>>> differently upstream. For example: >>>>>> >>>>>> db.Prepare("INSERT INTO userinfo(username, departname, created) >>>>>> values(?,?,?)") >>>>>> -> This could fail for basically two reasons: Either communication >>>>>> with your database somehow failed (e.g. a broken network connection), in >>>>>> which case you want to return the equivalent of an HTTP 503 error, or >>>>>> the >>>>>> syntax of your statement is wrong, in which case I'd argue panic'ing >>>>>> would >>>>>> be the correct thing - at the very least, returning the equivalent of a >>>>>> 500. >>>>>> >>>>>> stmt.Exec("astaxie", "研发部门", "2012-12-09") >>>>>> -> Either a 503. Or 400, 403, 409… >>>>>> >>>>>> res.LastInsertId() >>>>>> -> 500 or 501? >>>>>> >>>>>> The issue is, that by simply checking for nil and passing it along, >>>>>> you are *not handling your error*. Different error conditions require >>>>>> different error handling and what the correct error handling is, depends >>>>>> heavily on the application. An ENODIR error in one line of code can >>>>>> signify >>>>>> a totally different error condition than the same error two lines later. >>>>>> So >>>>>> all of these proposals are born out of an exception-style idea of how >>>>>> error >>>>>> handling is supposed to work; deep within the call stack something goes >>>>>> wrong and that something is then just bubbled up to be someone else's >>>>>> problem. Good error handling just can't be well abbreviated in this way >>>>>> - >>>>>> at least not generically. It's too application-specific for that. >>>>>> >>>>>> On Mon, Sep 4, 2017 at 8:27 PM, <marti...@programmfabrik.de> wrote: >>>>>> >>>>>>> Seriously? And yes, I have read >>>>>>> https://blog.golang.org/errors-are-values... >>>>>>> >>>>>>> The best case reduction I found is: >>>>>>> >>>>>>> ... >>>>>>> res, err = stmt.Exec("astaxieupdate", id) >>>>>>> checkError(err) >>>>>>> ... >>>>>>> >>>>>>> Still, I need this after each line of calling a function which may >>>>>>> return an error. >>>>>>> >>>>>> >>>>>> A better take-away from that blog post would have been, to orient >>>>>> yourself around the example of a writer given. You could, for example, >>>>>> provide a one-time abstraction that wraps *sql.DB and collects the >>>>>> error. >>>>>> I'd agree that the sql package tends to not be amazing for that, because >>>>>> of >>>>>> its set of interdependent types, it is still possible. For example, with >>>>>> this <https://play.golang.org/p/kdgBUqWeR->, you could write >>>>>> >>>>>> d := &errDB{db: d} >>>>>> stmt := d.Prepare("INSERT INTO…") >>>>>> res := stmt.Exec(…) >>>>>> id := res.LastInsertId() >>>>>> stmt := d.Prepare("UPDATE…") >>>>>> res := stmt.Exec(…, id) >>>>>> affect := res.RowsAffected() >>>>>> return d.err >>>>>> >>>>>> Now… this isn't really nice either (see above. sql isn't really >>>>>> well-designed for this. You'd probably try and implement a driver for >>>>>> this, >>>>>> but sql doesn't make that easy either). And it's a bad idea for all the >>>>>> same reasons the watch-proposal isn't a great idea here. But it >>>>>> illustrates >>>>>> a far more effective take-away from that blog post. >>>>>> >>>>>> >>>>>>> >>>>>>> I bet this is not pleasant to do in larger code bases and it also >>>>>>> takes away focus from what is actually happening. >>>>>>> >>>>>>> 50-80% of all lines of code in my example deal with error handling? >>>>>>> >>>>>>> This is not good. Seriously. >>>>>>> >>>>>>> And don't get me wrong, there is a lot of things I really like, love >>>>>>> and adore about Go, but catching errors needs an improved syntax! >>>>>>> >>>>>>> And I am not proposing try...catch here. >>>>>>> >>>>>>> How about introducing a new piece of syntax >>>>>>> >>>>>>> "watch if .... " >>>>>>> >>>>>>> which tells the compiler to watch out for changes in a given >>>>>>> SimpleStmt >>>>>>> >>>>>>> The same code as above would look like this: >>>>>>> >>>>>>> var err Error >>>>>>> >>>>>>> watch if err != nil { >>>>>>> // handle error(s) >>>>>>> } >>>>>>> >>>>>>> // insert >>>>>>> stmt, err := db.Prepare("INSERT INTO userinfo(username, departname, >>>>>>> created) values(?,?,?)") >>>>>>> res, err := stmt.Exec("astaxie", "研发部门", "2012-12-09") >>>>>>> id, err := res.LastInsertId() >>>>>>> fmt.Println(id) >>>>>>> >>>>>>> // update >>>>>>> stmt, err = db.Prepare("update userinfo set username=? where uid=?") >>>>>>> res, err = stmt.Exec("astaxieupdate", id) >>>>>>> affect, err := res.RowsAffected() >>>>>>> >>>>>>> >>>>>>> - The "watch if" would be executed after each assignment of any >>>>>>> of the variables used in SimpleStmt of the statement. >>>>>>> - Multiple "watch if" would be executed in order or appearance >>>>>>> - The "watch if" could be used like "defer..." inside functions >>>>>>> - The "watch if" would work in its full scope of the watched >>>>>>> variables >>>>>>> >>>>>>> I am not a language expert, so may be there is a saner way of >>>>>>> expression what I want to achieve. >>>>>>> >>>>>>> But bottom line is, there should by an easier to read and write way >>>>>>> to deal with errors in Go. >>>>>>> >>>>>>> >>>>>>> Martin >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> You received this message because you are subscribed to the Google >>>>>>> Groups "golang-nuts" group. >>>>>>> To unsubscribe from this group and stop receiving emails from it, >>>>>>> send an email to golang-nuts...@googlegroups.com. >>>>>>> For more options, visit https://groups.google.com/d/optout. >>>>>>> >>>>>> >>>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "golang-nuts" group. >>>>> To unsubscribe from this group and stop receiving emails from it, send >>>>> an email to golang-nuts...@googlegroups.com. >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>> >>>> -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.