What is the best way to reload a Fusebox app without getting "parsed file or directory not found" errors?

Mathachew picture Mathachew · Apr 25, 2009 · Viewed 10.9k times · Source

I have a site using CF8 and Fusebox 5. Anytime I need to add a new feature to the site, I usually have to add a new fuse to circuit.xml.cfm for either the controller, model, or view, or all. To enable these new features/pages, I go to the following url:

?fusebox.load=true&fusebox.parse=true&fusebox.password=password&fusebox.loadclean=true

The last parameter is one I recently picked up on and determined that using it would enable my new fuses; without it the new fuses are not recognized. However, when I do this, all of my parse files that were generated before are removed. This isn't much of a problem since they're regenerated on the fly when they are needed for the first time, but I have some pages that return errors when they are accessed. The error says directory not found, but they are there, each time this comes up it's because the parse file does not exist.

Here's an example of one error with the stack trace:

Error - Parsed File or Directory not found.

Date/Time: Apr 25 2009 12:26:02

Type: fusebox.missingParsedFile

Message: Parsed File or Directory not found.

Detail:

Attempting to execute the parsed file 'login.logout.cfm' threw an error. This can occur if the parsed file does not exist in the parsed directory or if the parsed directory itself is missing.
Stack Trace:
    coldfusion.runtime.CustomException: Parsed File or Directory not found.
    at coldfusion.tagext.lang.ThrowTag.doStartTag(ThrowTag.java:124)
    at coldfusion.runtime.CfJspPage._emptyTag(CfJspPage.java:2644)
    at cffusebox52ecfm1214986498.runPage(C:\example.com\fb5core\fusebox5.cfm:216)
    at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:192)
    at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:366)
    at coldfusion.runtime.CfJspPage._emptyTag(CfJspPage.java:2644)
    at cfindex2ecfm584653367.runPage(C:\example.com\index.cfm:3)
    at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:192)
    at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:366)
    at coldfusion.runtime.CfJspPage._emptyTag(CfJspPage.java:2644)
    at cfApplication2ecfc1103573364$funcONREQUEST.runFunction(C:\example.com\Application.cfc:36)
    at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:418)
    at coldfusion.runtime.UDFMethod$ReturnTypeFilter.invoke(UDFMethod.java:360)
    at coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:324)
    at coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:56)
    at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:277)
    at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:192)
    at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:448)
    at coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:308)
    at coldfusion.runtime.AppEventInvoker.invoke(AppEventInvoker.java:74)
    at coldfusion.runtime.AppEventInvoker.onRequest(AppEventInvoker.java:243)
    at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:269)
    at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)
    at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40)
    at coldfusion.filter.PathFilter.invoke(PathFilter.java:86)
    at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70)
    at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28)
    at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38)
    at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46)
    at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)
    at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22)
    at coldfusion.CfmServlet.service(CfmServlet.java:175)
    at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89)
    at jrun.servlet.FilterChain.doFilter(FilterChain.java:86)
    at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42)
    at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)
    at jrun.servlet.FilterChain.doFilter(FilterChain.java:94)
    at jrun.servlet.FilterChain.service(FilterChain.java:101)
    at jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106)
    at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)
    at jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:284)
    at jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)
    at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)
    at jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320)
    at jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)
    at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266)
    at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)

What I do to fix this problem is go to the following url, which is like the previous one, but without fusebox.loadclean=true:

?fusebox.password=password&fusebox.load=true&fusebox.parse=true

What I tried doing was after going to the first url, I would go to this second one, but the error still crops up.

What I'm looking for is the proper way to reload the circuits without generating these errors. I'm the third developer to get involved on this site, so the previous two may have had different styles of configuring each instance of circuit.xml.cfm. These files are used to determine the application flow of what includes are needed, additional security layers and specifying certain attributes. Here's the Fusebox method:

<!-- controller/circuit.xml.cfm -->
<circuit access="public">
    <fuseaction name="index">
        <set name="request.title" value="Account overview" />
        <do action="layout.header" />
        <do action="mdashboard.index" />
        <do action="vdashboard.index" />
        <do action="layout.footer" />
    </fuseaction>

    <fuseaction name="profile">
        <set name="request.title" value="Your Profile" />
        <do action="layout.header" />

        <!-- form submitted to the same page -->
        <if condition="isDefined('attributes.submit')">
            <true>
                <do action="mdashboard.updateprofile" />
                <do action="vdashboard.profile" />
            </true>
            <false>
                <do action="mdashboard.profile" />
                <do action="vdashboard.profile" />
            </false>
        </if>

        <do action="layout.footer" />
    </fuseaction>
</circuit>

<!-- model/circuit.xml.cfm -->
<circuit access="internal">
    <fuseaction name="index">
        <include template="sqlIndex" />
    </fuseaction>

    <fuseaction name="profile">
        <include template="sqlProfile" />
    </fuseaction>

    <fuseaction name="updateprofile">
        <include template="actUpdateProfile" />
    </fuseaction>
</circuit>

<!-- view/circuit.xml.cfm -->
<circuit access="internal">
    <fuseaction name="index">
        <include template="dspIndex" />
    </fuseaction>

    <fuseaction name="profile">
        <include template="dspProfile" />
    </fuseaction>
</circuit>

Here's the mixture of Fusebox and ColdFusion method:

<!-- controller/circuit.xml.cfm -->
<circuit access="public">
    <fuseaction name="index">
        <set name="request.title" value="Account overview" />
        <do action="layout.header" />
        <include template="ctrlIndex" />
        <do action="layout.footer" />
    </fuseaction>

    <fuseaction name="profile">
        <set name="request.title" value="Your Profile" />
        <do action="layout.header" />
        <include template="ctrlProfile" />
        <do action="layout.footer" />
    </fuseaction>
</circuit>

<!-- model/circuit.xml.cfm -->
<circuit access="internal">
</circuit>

<!-- view/circuit.xml.cfm -->
<circuit access="internal">
</circuit>

<!-- controller/ctrlProfile.cfm -->
<cfif isDefined("attributes.submit")>
    <cfinclude template="../model/actUpdateProfile.cfm">
</cfif>

<cfinclude template="../model/sqlPaymentOptions.cfm">
<cfinclude template="../view/dspPaymentOptions.cfm">

Both methods are employed throughout the site, and I'm not opposed to using either one, but my objective is to reduce any error that could come up when the user tries to access a particular page. I was thinking that maybe the problem is the mixed method of configurations, that I should stick with, say, the Fusebox method only, but I have not been able to find a common trend in this error. The error handler we have in place emails me each time a page receives an error, so I'm thinking that I could automatically call my 2nd url and redirect them back to the page that generated the error when this specific error occurs, but this has the potential for an infinite loop, and it doesn't address the real problem.

Am I going about this incorrectly? Is there set of attributes I can include in the url that will force the site to recognize new fuses without clearing my parse files? CF itself isn't difficult to code, but I'm still relatively new to it, so I could be going about this backwards. Thanks!

Answer

Peter Boughton picture Peter Boughton · Apr 25, 2009

NOTE: New fuses do not need a fusebox reload - only new fuseactions require one.

I'm not entirely certain if the errors you're getting are what I think they are, but the following is good practise regardless...

When you have made changes and need to reload fusebox, what you should do is this:

  1. Deploy the latest code to a pre-Live 'staging' area on the same server.
    • Generate your parsed files in this area using fusebox.parseall=true and fusebox.loadclean=true
    • Copy all files from there into your Live webroot.
    • Perform a fusebox fusebox.load=true on the Live site - nothing else (except password).

(Note: if necessary, before step 3 set your site to offline/maintenance mode, and then after step 4 put it back online again)