Forum Discussion

Russell_E_Glaue's avatar
Russell_E_Glaue
Icon for Nimbostratus rankNimbostratus
Feb 16, 2009

no 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

 

  • hoolio's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    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
  • 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
  • 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's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    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
  • 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's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    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
  • 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's avatar
    hoolio
    Icon for Cirrostratus rankCirrostratus
    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