CPB07
CPB07

Reputation: 699

CFTry Until Log In Successful

I have an API that has a 12-step log in process. The login succeeds most of the time but now and again it'll thrown an error (usually relating to a JSON parsing failure) and that is the end of the attempt.

I've never used CFTry but from having read up on it and looked at examples I was still unable to find an answer to this question...

Is it possible to put this whole login script in a CFTry block with a condition of trying to execute the script until the account has been logged in successfully?

Upvotes: 2

Views: 463

Answers (3)

nasaa
nasaa

Reputation: 2731

Well you can do it like this - Put you login call into a function and surround it with try catch block and inside the catch block call the main function till you succeed. It is more or less like a recursive function and it has its own pitfall like going into never ending loop and bringing down your server. But you can moderate that by setting a counter or something like that in application/session scope.

 <cffunction name="main">

    <cftry>
        <cfset success = login()>
    <cfcatch>
        <cfset main()>
    </cfcatch>
    </cftry>

  </cffunction>

  <cffunction name="login">
    <!--- Do login stuff here --->
  </cffunction>

Upvotes: 1

Jason Dean
Jason Dean

Reputation: 9615

<cftry> does not really work the way you think it does. But it could still be used in this situation when combined with <cfloop> and proper use of catches.

I have a similar issue where I have 3 authentication servers that need to be checked. If the first fails it checks the second, if the second fails it checks the third. I accomplish this with looping.

Now, I certainly DO NOT recommend that you "try until successful" unless you relish the idea of bringing your server to its knees when something unexpected happens. But you could do something like this pseudo CFML.

<cfloop from="1" to="3" index="authIndex">
    <cftry>
        <!--- Check JSON parsing result --->
        <cfif NOT isJSON(jsonData)>
            <cfthrow type="badJSON" message="JSON Parsing failure" />
        <cfelse>
            <cfset userData = deserializeJSON(jsonData) />
        </cfif>

        <cfif authUser(userData.userInfo, userData.userpassword)>
            <cfset session.user = {} />
            <cfset session.user.auth = true />
            <!--- whatever other auth success stuff you do --->
        <cfelse>
            <cfthrow type="badPassOrUsername" message="Username of password incorrect" />
        </cfif>

        <!--- If it makes it this far, login was successful. Exit the loop --->
        <cfbreak />

        <cfcatch type="badPassOrUsername">
            <!--- The server worked but the username or password were bad --->
            <cfset error = "Invalid username or password" />

            <!--- Exit the loop so it doesn't try again --->
            <cfbreak />
        </cfcatch>

        <cfcatch type="badJSON">
            <cfif authIndex LT 3>
                <cfcontinue />
            <cfelse>
                <!--- Do failure stuff here --->
                <cfset errorMessage = "Login Failed" />
                <cflog text="That JSON thing happened again" />
            </cfif>
        </cfcatch>
    </cftry>
</cfloop>

The above code will: - Only try once if the username or password is bad - Will try up to three times if the JSON parsing data occurs. - Will only try as many times as it needs to. Once it gets back a proper JSON response it should either auth or not and continue on.

Upvotes: 5

Dan Bracuk
Dan Bracuk

Reputation: 20794

Your plan is unlikely to work, but it might. cftry/cfcatch works like this

 <cftry>
 code
 <cfcatch>
 code that runs if there is an error.
 </cfcatch>
 </cftry>

If you want to try again, you can put that code block into a loop.

 <cfset success = "false">
 <cfloop condition= "success is 'false'">
 <cftry>
 code
 <cfset success = "true">

 <cfcatch>
 code that runs if there is an error.
 it has to change something since this is in a loop
 </cfcatch>
 </cftry>

However, if your error is json parsing, what are you going to change inside the cfcatch block so that your will eventually succeed?

Upvotes: 2

Related Questions