調試,是程式開發中的基本技巧。快速定位錯誤消息在源代碼中的位置,對發現和解決程式中的問題有着重要的意義。在SAP CRM中,錯誤消息通常在前台的Web Client頁面中展示,應該怎樣定位相關代碼的位置呢?
我在SAP的網站上面找到了一篇不錯的相關文章,翻譯在這裡。
英文原文:How to quickly locate the code where the error message is raised for Business Transaction Application
本文連結:http://www.cnblogs.com/hhelibeb/p/6269133.html
-------------------------------------------正文分割線------------------------------------------------------------
在我的部落格“六種調試技巧”中,Fabian Geyer提出了一個有關ERP應用查錯的很好的觀點。
他的原論述:
某些ERP應用(比如财務的)在“探測”到錯誤發生的時候經常使用一種“消息收集器”技術,特别是操作“多對象”的時候。“消息收集器”會被“存儲”在一個“錯誤集”裡面,在所有的檢查完成後,将會産生一個也許包含了多個錯誤的清單,并且通過彈窗或清單被展示出來。
在這些情況下,在消息被“展示”的時候對程式進行分析就太晚了,因為導緻錯誤發生的應用資料/環境在其它位置(在運作期間發生的更早)。在這些情形下,我通常在函數MESSAGE_STORE中設定斷點。
為防止BC Application日志技術帶來相同的問題(SLG0, SLG1等),可以在函數BAL_LOG_MSG_ADD中添加斷點。
實際上,CRM應用中的錯誤消息處理邏輯是一樣的,讓我使用服務合同處理的例子進行說明:
如何找到觸發消息CRM_ORDERADM_I編号505的代碼?
注:如果看不到錯誤消息的詳細資訊,請前往事務代碼SU3,維護使用者參數 BSPWD_USER_LEVEL = 6
方法1:使用源代碼掃描
有關如何使用源代碼掃描的細節,請參考我之前的博文。
為了寫部落格,我使用了這個方法來定位,隻花了幾分鐘就找到了準确的代碼位置。
首先我使用源代碼掃碼工具(搜尋關鍵字 = 505)來找消息号505的ITEM_TYPE_NOT_FOUND常量。因為我知道程式CRM_STATUS_CON已經定義了所有狀态的常量,是以我用如下的參數運作了搜尋程式:
結果如下:
接着再一次使用源代碼掃描器。這裡有個問題:怎樣指定輸入參數?
1,我們知道服務合同由One Order架構實作。随意打開一個函數子產品CRM_ORDER_*例如CRM_ORDER_READ,擷取它的包名CRM_ORDER:
2,輸入以下内容後執行搜尋程式:
什麼也沒找到。接着我把CRM_ORDER改為CRM_ORDER*,這次獲得了七個候選結果,然後在每個當中設定斷點,重複你觸發錯誤的場景。
證明了上面結果中的第三個是我們尋找的地方:
方法2:使用函數子產品 BAL_LOG_MSG_ADD
這個由Fabian Geyer提出的技巧也非常好。在函數子產品BAL_LOG_MSG_ADD中設定斷點,然後重複服務合同中的場景。斷點會被觸發(你可以觀察到這個函數子產品處于調用棧的最頂點),并且我們發現代碼的位置和方法1中找到的位置完全一樣。
在這個例子中,方法2的定位甚至比方法1更加有效率。感謝Fabian分享給我們如此有用的技巧。
在函數子產品BALW_BAPIRETURN_GET2中設定斷點也是一個不錯的嘗試。
為什麼兩個方法都無效?為什麼斷點沒能在我的應用中被觸發?
還是以服務合同為例,業務事務類似于銷售訂單、服務訂單和服務合同經由所謂的One Order架構實作。按照我在上面最開始的部分引用過的Fabian的論述,One Order架構的探測邏輯——在這個例子裡即是DETERMINE_ITEM_TYPE中的邏輯——隻是在這個項目第一次被插入的時候起作用。一旦發現錯誤,函數組CRM_MESSAGES中各自的函數子產品會被調用來持有錯誤消息。之後在錯誤的服務合同再次被打開的時候,就不會再有項目的類型檢查了。相反,錯誤消息經由讀取這個函數組中的函數子產品來擷取,并顯示在UI上面。
當我在服務合同删除一個項目産品時,對于這個項目來說已經過時的錯誤資訊也會同時通過CRM_MESSAGES_DELETE删除。
是以當我在難以命中業務事務應用中出現的錯誤消息時,我會選擇删除舊的錯誤項目、重建它,或者從頭開始建立一個新的。當然,如果我們需要在生産系統調試,這兩個辦法都不合适。
在這種情況下,如果你能確定客戶生産系統中出現的錯誤消息也能在你的開發系統中重制,你還是可以使用本文中提到的技巧,用高效率的方式找到相應代碼的位置。