Forum Discussion
Russell_E_Glaue
Nimbostratus
Feb 16, 2009no such pool Failed Tcl_pool_GetFromObj
I am receiving this error message, and cannot determine why it is occurring. I cannot even use TCL 'catch' to catch the error.
Feb 16 13:22:48 tmm tmm[1568]: 01220001:3: TCL error: dist__virtualhosting - no such pool Failed Tcl_pool_GetFromObj: pool (line 1) invoked from within "pool $http_host_pool"
Feb 16 13:22:48 tmm tmm[1568]: 01220001:3: TCL error: dist__virtualhosting - no such pool Failed Tcl_pool_GetFromObj: pool (line 14) invoked from within "pool $http_host_pool"
Here is the iRule:
-
when HTTP_REQUEST {
discover the server pool
set http_host_pool [HTTP::host]_pool
if { $http_host_pool equals "_pool" } {
log local0.err "The HTTP Host, [HTTP::host], is not defined."
}
if { [findstr $http_host_pool "www." 0 "4"] eq "www." } {
set http_host_pool [substr $http_host_pool 4 end]
}
test that the server pool exists
if { [catch [pool $http_host_pool] result] }{
log local0.err "pool $http_host_pool does not exist, Request: [HTTP::host][HTTP::uri], Result: $result"
}
set the server pool
pool $http_host_pool
}
-
I am confused: If there were really "no such pool...", then my iRule should log that the pool does not exist after this error is caught using "catch". But that is not happening. It looks like the error is not being caught at all.
Does anyone know why this is occurring?
-RG
8 Replies
- hoolio
Cirrostratus
Hi RG,
When you use catch, the command is actually executed. If the execution returns an error then catch handles the error and returns 1. Else if there isn't an error, catch returns 0. You're executing the pool command after the catch statement regardless of whether there was an error caught or not. So I expect that pool command to generate a TCL error if the pool doesn't exist.
Also, the host header isn't case sensitive so it would be a good idea to set it to lowercase. And finally, selecting the pool based on the Host header (or any other client-supplied information) would potentially open a security hole which would allow a client to access any pool configured on the BIG-IP.when HTTP_REQUEST { discover the server pool set http_host_pool [string tolower [HTTP::host]]_pool if { $http_host_pool equals "_pool" } { log local0.err "The HTTP Host, [HTTP::host], is not defined." } if { [findstr $http_host_pool "www." 0 "4"] eq "www." } { set http_host_pool [substr $http_host_pool 4 end] } Try to use the pool. If it doesn't exist, log an error. if { [catch [pool $http_host_pool] result] }{ log local0.err "pool $http_host_pool does not exist, Request: [HTTP::host][HTTP::uri], Result: $result" } else { log local0.err "pool $http_host_pool does exist, Request: [HTTP::host][HTTP::uri], Result: $result" } }
Aaron - Russell_E_Glaue
Nimbostratus
I changed my catch statement to the following:
-
if { [catch {set test [active_members $http_host_pool]} result] }{
log local0.err "pool $http_host_pool does not exist or has no active members, Request: [HTTP::host][HTTP::uri], Result: $result"
}
-
And this revealed the HTTP request information the TCL error was resulting from.
This now resolves this matter.
However - I do not understand why TCL produced the error, but was not caught in my 'catch' statement.
-RG - Russell_E_Glaue
Nimbostratus
Posted By hoolio on 02/16/2009 11:59 AM
... You're executing the pool command after the catch statement regardless of whether there was an error caught or not. So I expect that pool command to generate a TCL error if the pool doesn't exist...Aaron
Then, when the pool command is referring to a nonexisting pool, why does it not return an error to be caught by the catch command?
I know issuing the pool command does not exit. So either:
1) executing pool with a nonexisting pool causes a TCL error that exists the iRule, or
2) executing pool with a nonexisting pool does not throw an error that will get caught by the TCL catch command.
Does anyone know why?
-RG - hoolio
Cirrostratus
Hi RG,
The code within the catch statement is executed. Catch handles the error if one occurs and allows any subsequent code to be executed normally. So the example I posted above should work fine to try to assign the pool and otherwise log an error message if the pool doesn't exist. If you added more code after the catch statement, it would be run after the catch statement runs regardless of whether the code within the catch statement generated an error or not.
Here are a few examples of using catch:
iRule test:return 0 is false. Save the result of running the command 'return 0' to the variable named result if {[catch {return 0} result]}{ log local0. "catch was true, because return resulted in return code 0. Result: $result" } else { log local0. "catch was false, because return resulted in non-zero return code. Result: $result" }
Log output:
Rule : catch was true, because return resulted in return code 0. Result: 0
iRule test:if {[catch {set test 1} result] }{ log local0. "catch was true, because the set command returned with an error. Result: $result" } else { log local0. "catch was false, because the set command returned without error. Result: $result" } This log statement will run regardless of whether there is an error or not log local0. "\$test: $test (This log statement will run regardless of whether there is an error or not)"
Log output:
Rule : catch was false, because the set command returned without error. Result: 1
Rule : $test: 1 (This log statement will run regardless of whether there is an error or not)
iRule test:if {[catch {set test $var_that_doesnt_exist} result]}{ log local0. "catch was true, because the set command returned with an error. Result: $result " } else { log local0. "catch was false, because the set command returned without error. Result: $result" }
Log output:
Rule : catch was true, because the set command returned with an error. Result: can't read "var_that_doesnt_exist": no such variable
Aaron - Russell_E_Glaue
Nimbostratus
Thanks - but I know all of this already.
In fact, I saw this information you are providing on catch in another post in the forums.
This does not answer my question.
I have this irule code:if { [catch [pool $http_host_pool] result] }{ log local0.err "pool $http_host_pool does not exist, Request: [HTTP::host][HTTP::uri], Result: $result" }
BUT when the pool does not exist, the log message is not logged.
This is the problem.
It seems that the pool command does not return an error (thus making catch true) when the pool does not exist.
Is this a bug?
Or is this intended?
-RG - hoolio
Cirrostratus
Sorry... I wasn't sure which part you were asking about. I think the problem is with the syntax you were using. If you wrap the statement being caught in square brackets [ ], that gets executed and is not handled as expected by catch. If you use curly braces { }, it should work and give you the output in $result.
Here is an example which shows the catch result:when HTTP_REQUEST { set pool_name "non_existent_pool" if {[catch {pool $pool_name} result]}{ log local0. "Caught error: $result" } }
The logged value for $result is:
Caught error: no such pool
Aaron - Russell_E_Glaue
Nimbostratus
Ahh!
Thanks.
That explains why this worked:if { [catch {set test [active_members $http_host_pool]} result] }{
And this did not:if { [catch [pool $http_host_pool] result] }{
May I guess that this would then work:if { [catch {[pool $http_host_pool]} result] }{ - hoolio
Cirrostratus
Catch will execute the code within the curly braces. It seems to work if you add square braces, but it shouldn't be necessary.
Aaron
Recent Discussions
Related Content
DevCentral Quicklinks
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com
Discover DevCentral Connects
