Re: Terminating a macro on error

Daniel Dekany <[email protected]>
Newsgroups gmane.comp.web.freemarker.user
Message-ID <[email protected]>
Friday, February 18, 2011, 9:10:38 PM, Chris wrote:

> I'm guessing there isn't an answer to this one, but thought I'd ask:
>
> We've got a macro that looks like this:
>
> <#macro foo>
>    <#assign bar = myMethod()/>
>    Render ${bar} and do other stuff.
> </#macro>
>
> myMethod() is a TemplateMethodModelEx. Sometimes it throws exceptions. I
> trap these exceptions with a simple TemplateExceptionHandler that just
> writes the error to the output.
>
> The trouble is that the macro continues to execute after the exception
> happens. I'd prefer that it just terminate and resume rendering the page
> after the macro.
>
> Is there some kind of magic I can do in the TemplateException handler 
> that would look forward in the parse tree to the end of the macro, and
> resume execution there?

No, there isn't. But I belive it's possible to write a user-defined
directive (a TemplateDirectiveModel) to achieve a similar effect. Note
that FTL has #attempt/#recover directives, which do something similar
that you need, but they won't kick in if the error handler suppresses
the exceptions, so... you need an user-defined directive instead, and
let's call this directive "attempt", and it would be used like this:

  <#macro foo>
    <@attempt>
      <#assign bar = myMethod()/>
      Render ${bar} and do other stuff.
    </@attempt>
  </#macro>

So here it explicitly mark the section where you need this special
kind of error handling. This "attempt" should have access to the
TemplateExceptionHandler object, which must be of a known custom
class, so the directive can disable the suppressing of exceptions
inside it's nested content (using a method of the error handler), and
catch the exceptions thrown there itself, stopping their further
propagation. To handle the exception, you should just call the error
handler to print the error message (again, it's of a custom class, so
it could have a printErrorMessage(Writer) method or something). You
may also want to roll back the output generated within the nested
content (for that you need to replace the output Writer with a
StringBuilder (or something more efficient) before calling the nested
content - see how #attempt/#recover does that).

-- 
Best regards,
 Daniel Dekany


------------------------------------------------------------------------------
The ultimate all-in-one performance toolkit: Intel(R) Parallel Studio XE:
Pinpoint memory and threading errors before they happen.
Find and fix more than 250 security defects in the development cycle.
Locate bottlenecks in serial and parallel code that limit performance.
http://p.sf.net/sfu/intel-dev2devfeb
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.