-
Notifications
You must be signed in to change notification settings - Fork 115
Introduce try/catch control structure #152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
try/end or try/recover/end execute a list of statements, recovering from any panic (runtime errors) inside. when using try with recover, the statement list inside recover/end is executed in the event of a recovery. recover takes an optional identifier name under which the error will be available inside the recover statement list. in case of no runtime error, the output generated by the try statement list will be kept. in case of any panic, no output from the try statement list will be kept.
Brilliant! (I didn't deep-dive into the internals to review what you did but the concept is great.) Do you think it will affect performance much? Probably only if you're dealing with tons of panics, I imagine. |
Well it only impacts performance when you actually use it. If you use it, there's certainly a hit to the speed of outputting rendered results and an increase in memory consumption, because we buffer output until the entire block was executed. Other than that, it shouldn't have a big impact, it only shuffles around a few variables before and after executing the statement list. Deferred functions don't have any significant overhead in recent Go versions, either, so the panic handling should be ok, too. |
I liked the suggestion to rename "recover" to "catch" you had here: #151 (comment). Coming up! |
That makes sense. Yeah, it's something you can use if you need it.
👍 I think this is great, a good tool for the arsenal :) |
I broke this in 2e37ce4, forgetting it's an exported function
…e() which was exported via Set() if setValue() couldn't find a variable with the given name in any of the scopes, it would create the variable in the top-most one instead of the current one. 6e9c5b9 fixed this, but outside code might depend on this bug to set global variables via Set(), so SetGlobal() can now be used to do that.
this broke in 2e37ce4, too. oops.
to ensure it's still possible to create new vars via the Runtime API, there's a new Let() method (which might shadow a var existing in a parent scope), as well as SetOrLet() which does the right thing for you, depending on if a var with the given name exists or not.
Sweet! 🎉 Are you going to tag v3.0.1? :) |
Very likely will tag v4.0.0 soon, there are breaking API changes once again... 🤷♂️ |
Huh, kk, I mean this is not breaking right, it's additive? Would it make sense to tag it before you do the major version jump? |
Huh, hadn't noticed that earlier. Yeah, makes sense. |
{{try}} .. {{end}}
or{{try}} .. {{catch [err]}} .. {{end}}
executes a list of statements, recovering from any panic (runtime errors) inside. When using try with catch, the statement list inside catch/end is executed in the event of a recovery.catch takes an optional identifier name under which the error will be available inside the catch statement list.
In case of no runtime error, the output generated by the try statement list will be kept. In case of any panic, no output from the try statement list will be kept.
Born out of the ashes of #151.