Lucee 6, better cftry and cfdocument

what do you do when you have to test without cftry?
I guess like me. Add comments like these:

<!--- <cftry> ---->

    <cf_doSomething>

<!----
    <cfcatch type="any">
       <cfabort>
    </cfcatch>
</cftry>
---->

to avoid these comments you could add a “disabled” attribute to the tag to produce the same result:

<cftry disabled=true> 
    <cf_doSomething>

    <cfcatch type="any">
       <cfabort>
    </cfcatch>
</cftry>

you like it?

9 Likes

that does seem rather neat!

1 Like

Hi!

Good idea!

Now is it better to have a disabled attribute or an enabled attribute with default true?

<cftry enabled=false> 
    <cf_doSomething>

    <cfcatch type="any">
       <cfabort>
    </cfcatch>
</cftry>
3 Likes

It’s a good idea, instead of commenting out the try/catch, I usually add <cfrethrow> inside of the catch statement

6 Likes

I do really like it!!!

1 Like

yes, this is better :slight_smile:

we have the same for cfdump (<cfdump> :: Lucee Documentation)
“enabled:dumps are enabled by default, pass false to short circuit a dump execution and effectively disable it”

The handy thing with this is, you then can do the following in the Application.cfc

this.tag.cfdump.enabled=false;

to disable all dumps (unless tehex have set that attribute explicitly).

having “enabled” would be consistent with existing implementation (dump).

5 Likes

ok @Roberto_Marzialetti can you file an enhancement?

Done:
https://luceeserver.atlassian.net/browse/LDEV-3628
:slight_smile:

3 Likes

Hey,

you can also simply change cfcatch’s “type” attribute. It accepts arbitrary strings and cfcatch will only kick in if this “type” matches the exception’s actual type.

I usually do it like this:

<cftry> 
    <cf_doSomething>

    <cfcatch type="never_mind">
       <cfabort>
    </cfcatch>
</cftry>
2 Likes

and in cfscript?

I’m not a heavy cfscript user, but I imagine this would be possible:

try (enabled=false) {
    x = 5/0;
}
catch (any e) {
    writeOutput("Error: " & e.message);
}

or depending on the standard established for the other tags in the cfscript for Lucee (ex: like thread in ACF9), this could also be

try enabled=false {
    x = 5/0;
}
catch (any e) {
    writeOutput("Error: " & e.message);
}

I prefer the first one.

1 Like

@micstriit Does this mean the enhancement might allow for

this.tag.cftry.enabled=false;
2 Likes

you can also simply change cfcatch’s “type” attribute.

Yeah. That’s a better approach.

Or a <cfdump var="#cfcatch#" abort="true"> at the top of the catch block. Job done.

I think this feature is dangerous as it will encourage code to run differently in dev than in production (esp with the suggested this.tag.cftry.enabled=#runtimeValue#). No-one ought to want that. It’s fine with <cfdump> as it’s just output; this is flow control.

I also suspect it’s an enabler for ppl who don’t write tests; tested code would way less often require one to comment out flow-control constructs to check behaviour.

Seems like busywork to me, and solving a problem that is a) already solved; b) can leave code unstable. Let’s not enable that sort of thing in our dev community.

1 Like

I would discourage this, as I consider it to be superfluous. What you propose causes unnecessary bloat.

Besides, it contains a self-contradiction. Namely, “with” as a solution for “without”.

Your question,

@Roberto_Marzialetti : what do you do when you have to test without cftry?

is equivalent to

what do you do when you have to try a piece of code without cftry?

Simple answer: omit cftry.

The use case for me would be in dev/test you may have servers that go up and down and so services may or may not be available in that environment that in productionyou want an error to be pushed, but in dev it might not matter if that service is alive. That way you can run code with graceful fail.

So could make that senario better. (only thought about this for five minutes)

Ironically I could see try / catch as a perfect place to put the cftimer idea that Gert was talking at on the cfcamp cfalive…

ie:
cftry timeout="10"

or

put it in catch(type=timer, time="10"

Where is is solved in your view? (trying to understand the use-case you assume)

@dawesi: The use case for me would be in dev/test you may have servers that go up and down and so services may or may not be available in that environment that in production you want an error to be pushed, but in dev it might not matter if that service is alive. That way you can run code with graceful fail.

As you are undoubtedly aware, a common best-practice in software development is the phased DTAP cycle (Development, Testing, Acceptance, Production). Following this best-practice, whatever is in the production environment has already been tested, tried out and accepted in the preceding DTA phase.

The idea is to avoid surprises in production. In other words, to avoid the sort of scenarios you describe.

But accidents will happen, people say. If an unforeseen problem occurs in production, it will then become the new task for the next DTAP cycle.

Not sure what best practice has to do with my comment. You can do DTAP perfectly well with systems not operational in other stages. Complex environments demand this, especially when you aren’t in control of systems or servers, or they are 3rd party. DTAP is one of several ‘best practice’ methodologies for testing.

Do i not test my facebook posting feature as the linked in server is down during testing? both use the same part of my app (the social posting feature)? This is just one example.

There are many dev/test environments (eg govt) where you have no control if other dev/test servers are running when you’re testing. That doesn’t invalidate testing on other parts of the app that dont directly rely on that service for that page, but would normally load that service into the application.

That said my comment doesn’t change DTAP, it’s purely a config option for monolithic systems that rely in some parts on 2ndary systems, there is many reasons to run different code for different environments (aka config files).

Either way, adding a perfectly valid test case IMHO. .

could have abort=“true” or abort=“10” for timeouts that gert wants and kill two birds with one stone :wink: