Stop code when a condition is true - return

I am trying to build a safety that will check for a condition that will either be true or false. This will be called multiple times through out a long bit of code. if the condition is true it will cause the rest of the code to stop. I cant seem to figure it out. Can someone point me in the right direction? By the way Exit will not work as it will close the whole program that I use.
proc _CheckEsc {} {
if {condition is true} {
return
}
return
}
proc testType {} {
set TestResult 0
while {$TestResult < 10} {
_CheckEsc;
incr TestResult
}
return;
}

You can make _CheckEsc stop it's caller by using some of the more advanced features of return. In particular, we can use it to make _CheckEsc act itself like a break or a return.
This mechanism is very much like throwing an exception in other languages (and in fact you can regard Tcl as having special exception classes for return, break and continue, except things are rather more complicated than that under the covers).
Making the caller's loop stop
proc _CheckEsc {} {
if {condition is true} {
return -code break
}
}
Making the caller return
proc _CheckEsc {} {
if {condition is true} {
return -level 2
# Or, if you want to return a value from the caller:
### return -level 2 "the value to return"
}
}
Note that the -level option isn't supported in Tcl 8.4 and before; that limits what you can do with it, but your use case works provided you do this instead:
proc _CheckEsc {} {
if {condition is true} {
return -code return
# Or, if you want to return a value from the caller:
### return -code return "the value to return"
}
}

Will something like this works for you?
proc _CheckEsc {} {
return {condition is true}; # I don't know what you have here
}
proc testType {} {
set TestResult 0
while {_CheckEsc && $TestResult < 10} {
incr TestResult
}
}
You can help us out by being more specific of what _CheckEsc does.

Related

Issue with CRMContainer in Twilio Flex

I built a simple plugin that shows in the CRMContainer the url of my CRM given some attributes parameters (if they are passed by), during inbound tasks this works fine, but the problem is that during outbound calls the behaviour is not the one expected, this is the piece of code:
flex.CRMContainer.defaultProps.uriCallback = (task) => {
return task
? `https://mycrm.zzz/${task.attributes.clicar}/${task.attributes.contacth}/`
: 'https://mycrm.zzz/contacts/';
}
}
I would need an additional condition that tells the code, if this is an outbound voice call to always show a default url.
I tried adding an if/else that checks if task.attributes.direction is outbound, but Flex says this is undefined.
Any tip?
Thanks
Max
The problem is that you aren't checking for the existence of the task. Your original code had this:
flex.CRMContainer.defaultProps.uriCallback = (task) => {
return task
? `https://mycrm.zzz/${task.attributes.clicar}/${task.attributes.contacth}/`
: 'https://mycrm.zzz/contacts/';
}
}
Which returns the URL with the task attributes in it only if the task exists, because of the ternary conditional.
So, when you try to use the attributes you need to make sure the task exists. So taking your code from the last comment, it should look like this:
flex.CRMContainer.defaultProps.uriCallback = (task) => {
if (task) {
if (task.attributes.direction === 'outbound'){
return `https://mycrm.zzz/${task.attributes.clicar}/${task.attributes.contacth}/`;
} else {
return `https://mycrm.zzz/contacts/`
}
} else {
return 'https://mycrm.zzz/contacts/';
}
}

Jenkins timeout/abort exception

We have a Jenkins pipeline script that requests approval from the user after all the preparatory steps are complete, before it actually applies the changes.
We want to add a timeout to this step, so that if there is no input from the user then the build is aborted, and are currently working on using this kind of method:
try {
timeout(time: 30, unit: 'SECONDS') {
userInput = input("Apply changes?")
}
} catch(err) {
def user = err.getCauses()[0].getUser()
if (user.toString == 'SYSTEM') { // if it's system it's a timeout
didTimeout = true
echo "Build timed out at approval step"
} else if (userInput == false) { // if not and input is false it's the user
echo "Build aborted by: [${user}]"
}
}
This code is based on examples found here: https://support.cloudbees.com/hc/en-us/articles/226554067-Pipeline-How-to-add-an-input-step-with-timeout-that-continues-if-timeout-is-reached-using-a-default-value and other places online, but I really dislike catching all errors then working out what's caused the exception using err.getCauses()[0].getUser(). I'd rather explicitly catch(TimeoutException) or something like that.
So my question is, what are the actual exceptions that would be thrown by either the approval step timing out or the userInput being false? I haven't been able to find anything in the docs or Jenkins codebase so far about this.
The exception class they are referring to is org.jenkinsci.plugins.workflow.steps.FlowInterruptedException.
Cannot believe that this is an example provided by CloudBeeds.
Most (or probably all?) other exceptions won't even have the getCauses() method which of course would throw another exception then from within the catch block.
Furthermore as you already mentioned it is not a good idea to just catch all exceptions.
Edit:
By the way: Scrolling further down that post - in the comments - there you'll find an example catching a FlowInterruptedException.
Rather old topic, but it helped me, and I've done some more research on it.
As I figured out, FlowInterruptedException's getCauses()[0] has .getUser() only when class of getCauses()[0] is org.jenkinsci.plugins.workflow.support.steps.input.Rejection. It is so only when timeout occured while input was active. But, if timeout occured not in input, getCause()[0] will contain object of another class: org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution$ExceededTimeout (directly mentioning timeout).
So, I end up with this:
def is_interrupted_by_timeout(org.jenkinsci.plugins.workflow.steps.FlowInterruptedException e, Boolean throw_again=true) {
// if cause is not determined, re-throw exception
try {
def cause = e.getCauses()[0]
def cause_class = cause.getClass()
//echo("cause ${cause} class: ${cause_class}")
if( cause_class == org.jenkinsci.plugins.workflow.steps.TimeoutStepExecution$ExceededTimeout ) {
// strong detection
return true
} else if( cause_class == org.jenkinsci.plugins.workflow.support.steps.input.Rejection ) {
// indirect detection
def user = cause.getUser()
if( user.toString().equals('SYSTEM') ) {
return true
} else {
return false
}
}
} catch(org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException e_access) {
// here, we may deal with situation when restricted methods are not approved:
// show message and Jengins' admin will copy/paste and execute them only once per Jenkins installation.
error('''
To run this job, Jenkins admin needs to approve some Java methods.
There are two possible ways to do this:
1. (better) run this code in Jenkins Console (URL: /script):
import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval;
def scriptApproval = ScriptApproval.get()
scriptApproval.approveSignature('method org.jenkinsci.plugins.workflow.steps.FlowInterruptedException getCauses')
scriptApproval.approveSignature('method org.jenkinsci.plugins.workflow.support.steps.input.Rejection getUser')
scriptApproval.save()
'''.stripIndent())
return null
}
if( throw_again ) {
throw e
} else {
return null
}
}
And now, you may catch it with something like this:
try {
...
} catch (org.jenkinsci.plugins.workflow.steps.FlowInterruptedException err) {
if( is_interrupted_by_timeout(err) ) {
echo('It is timeout!')
}
}
P.S. I agree, this is bad Jenkins design.

Sleep inside Future in Scala.js

Is it possible to sleep inside a Future in Scala.js ?
Something like:
Future {
Thread.sleep(1000)
println("ready")
}
If I try this then I get an exception saying that sleep method does not exist.
It seems like that it is possible to sleep in JS : What is the JavaScript version of sleep()? even though it is not possible to block.
You cannot really pause in the middle of the future body, but you can register your future as a followup to a "delay" Future, which you can define as:
def delay(milliseconds: Int): Future[Unit] = {
val p = Promise[Unit]()
js.timers.setTimeout(milliseconds) {
p.success(())
}
p.future
}
and which you can then use as:
val readyLater = for {
delayed <- delay(1000)
} yield {
println("ready")
}

Jenkins Active Choices Parameter plugin not working as expected

I have a hidden parameter in Jenkins called platformType. I want to display choices based on the parameter platformType. I created the following groovy script but it doesn't work
if (platformType.equals("android")) {
return ['7.0', '6.0']
} else (platformType.equals("ios")) {
return ['10.0', '9.0']
}
Pls see the screenshot below
quite sure you did not specify the platformType as a parameter to platformVersion or you have other error in your code..
without error handling you just don't see it.
in your script you can catch the exception like this:
try {
if (platformType.equals("android")) {
return ['7.0', '6.0']
} else if(platformType.equals("ios")) {
return ['10.0', '9.0']
}
}catch(e){ return [e.toString()] }
in this case you'll see the error in your choice field
Looks you are missing if in the else part.
It is supposed to be:
if ('android' == platformType) {
return ['7.0', '6.0']
} else if ('ios' == platformType) {
return ['10.0', '9.0']
} else return []

Tcl Script: Invalid command name return when executing proc body

In a Tcl script, I want to catch the return of a Tcl proc in order to execute some finalization actions.
For example my code could be as follows:
proc X10 { a } { return [expr $a * 10] }
proc procF {} {
set a 13
catch {[info body X10]} __result
return $__result
}
procF
The previous code gives me an error: invalid command name " return [expr $a * 10] "
Although that replacing info body X10 with return [expr $a * 10] works as expected. What I initially thought is that both of them are exchangeable and should give the same output. So, why the first gives an error and what is the difference between both of them ?
Your code is failing because you are getting the body of X10 and treating that as a command name. Tcl doesn't split things up automatically for you — you have to ask for it — and this is a critical language safety factor. You'd have to do something like this:
proc procF {} {
set a 13
catch {eval [info body X10]} __result
return __result
}
or this (because the first argument to catch is a script):
proc procF {} {
set a 13
catch [info body X10] __result
return __result
}
But I'd actually be inclined in your case (as presented exactly, and trying to interpret what you've said) to do:
proc procF {} {
set a 13
catch {X10 $a} __result
return __result
}
Note also that if you did this:
proc procF {} {
set a 13
catch {info body X10} __result
return __result
}
then the result would be the definition of X10 without it being evaluated.

Resources