2017-12-16 8 views
0

私は最近、Applicationスコープにインスタンス化されるCFCでこの関数を作成しました:それはで時速数百回、何千、何回、時には数十を実行しますスプリアス、断続的に、変数未定義エラー

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; 
} 

同じリクエストですが、数時間おきにエラーが発生しています(上記のコードの行に常に表示されている行にあります)。 。エラーが発生したときに使用された入力と同じ入力は、後で正常に動作します。主に、私はそれが最初に投げられるべきである方法を見ることができません。

呼び出される関数(real_url_for)が未定義の値を返す可能性がありますが、同じvar results='';を持ち、その変数がこの関数に返すものである可能性があると考えました。

この関連性はありますが、application.cfmファイルにはラッパー関数app_url_for()が定義されています。これは単にこの関数の値を呼び出して返します。これは、Application.URLManager.url_for()を全面的に参照する必要を避けるためです。

これは私に困ってしまった。私は変数の存在を確認できると思いますが、そうする必要はありません。ここで

real_url_for機能です:

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; 
} 

私は両方の機能にvar key='';を追加してみてください、それが助けかどうかを確認します。

+0

さまざまなリークのため競合状態に似ています。コードをスキミングする私はvarスコープでない変数である "key"を少なくとも1つ見ています。最初に呼び出された関数をチェックし、すべての関数ローカル変数がローカライズされていることを確認します。 – Ageax

+0

'real_url_for'にコードを表示できますか?可変漏れ(少なくとも 'url_for'では)は問題を説明しませんが、@Ageaxはまだ正しいです。 – Alex

+0

https://stackoverflow.com/questions/34164252/losing-variable-element-is-undefined-in-variables –

答えて

1

さまざまなリークに起因する競合状態に似ています。コードをスキミングする変数スコープでない変数が少なくとも1つあります:key。コンポーネントがapplicationスコープに格納されているため、複数のスレッドが同時にその変数への読み書きを終了するため、エラーや奇妙な結果が発生します。

まず、呼び出された関数を確認します。すべての関数ローカル変数が適切にローカライズされていることを確認します。

1

key変数を各関数にローカルとして宣言すると、問題が解決されたようです。 4日以上は再発しません。フィードバックをいただいたすべての人に感謝します。

+1

特に、コードの元の作者でない場合は、可変リークをトラブルシューティングするのが非常に難しい場合があります。これが良いスコープが重要な理由です。あなたはそれを固定してうれしいです。 – Shawn