JoeCopley
JoeCopley

Reputation: 51

spurious, intermittent, variable undefined error

I recently created this function in a CFC which is instantiated into the Application scope:

Public String function url_for(path='') {
    var results = '';
    var these_parms = '';
    var parm_delim = '?';
    for (key in Arguments) {
        if (len(Arguments[key])) {
            switch(key) {
                case "path":
                    results = '#arguments[key]#';
                    break;
                case "template":
                    results = '/cf/#arguments[key]#';
                    break;
                case "productid":
                    if (NOT comparenocase(left(arguments[key],2),'p_'))
                        results = real_url_for(partno=replace(arguments[key],'p_',''));
                    else
                        results = real_url_for(productid=arguments[key]);
                    break;
                case "categoryid":
                    results = real_url_for(categoryid=arguments[key]);
                    break;
                case "specialid":
                    results = real_url_for(specialid=arguments[key]);
                    break;
                case "partno":
                    if (NOT len(arguments['path']))
                        results = real_url_for(partno=arguments[key]);
                    else
                        these_parms = listappend(these_parms,'#key#=#urlencodedformat(arguments[key])#','&');
                    break;
                case "parms":
                    these_parms = listappend(these_parms,'#arguments[key]#','&');
                    break;
                default:
                    these_parms = listappend(these_parms,'#key#=#urlencodedformat(arguments[key])#','&');
                    break;
            }
        }
    }
    if (len(results)) { //*********** error always occurs here 
        for (var i=1;i LTE variables.rewritequery.recordcount;i=i+1) {
            if (NOT comparenocase(variables.rewritequery.internalurl[i], results)) {
                results = variables.rewritequery.externalurl[i];
                break;
            }
        }
    }
    if (len(results) AND len(these_parms)) {
        if (listlen(results,'?') GT 1)
            parm_delim = '&';
        results = listappend(results, these_parms, parm_delim);
    }
    return results;
}

It gets run hundreds or thousands of times per hour, sometimes dozens of times in the same request, but every few hours or so it is throwing an error (always at the line marked in the code above): Variable RESULTS is undefined

I can detect no pattern for when, how or why it gets thrown. The same inputs used when the error occurs will work fine seconds later. Mainly, I cannot see how it should ever get thrown in the first place.

I thought it might be possible that the function being called (real_url_for) might be returning an undefined value, but it has the same var results='';, and that variable is what it returns to this function.

Don't know if this relevant, but the application.cfm file defines a wrapper function, app_url_for(), which simply calls and returns the value of this function. This is to avoid having to reference Application.URLManager.url_for() all over the place.

This has me stumped. I suppose I could check for the existence of the variable, but it shouldn't be necessary to do so.

Here is the real_url_for function:

Private String function real_url_for() {
    var results = '';
    for (key in Arguments) {
        if (len(Arguments[key])) {
            switch(key) {
                case "productid":
                    results = '/cf/displaylearnmore.cfm?#key#=#arguments[key]#';
                    break;
                case "categoryid":
                    results = '/cf/learnmorelist.cfm?#key#=#arguments[key]#';
                    break;
                case "specialid":
                    results = '/cf/displayspecial.cfm?#key#=#arguments[key]#';
                    break;
                case "partno":
                    results = '/part/#arguments[key]#';
                    break;
            }
        }
    }
    return results;
}

I'll try adding var key=''; to both functions and see if that helps.

Upvotes: 0

Views: 166

Answers (2)

JoeCopley
JoeCopley

Reputation: 51

Declaring the key variable as local to each function seems to have fixed the problem. It has no recurred for over four days. Thanks to all who provided feedback.

Upvotes: 1

SOS
SOS

Reputation: 6550

Sounds like race conditions due to variable leakage. Skimming the code I see at least one variable that is not var scoped: key. As the component is stored in the application scope, multiple threads easily end up reading/writing to that variable at the same time, causing errors or strange results.

First check the function(s) called. Verify ALL of the function local variables are properly localized.

Upvotes: 1

Related Questions