VisualForce Exception page
Czyli coś poszło nie tak... ale co?
Zapewne każdy z nas wielokrotnie spotkał się z problemem wysypania się aplikacji na jakiejś stronie i wyświetleniu pięknego komunikatu Salesforce Exception.
Powyższy komunikat mówi nam tylko tyle, że coś poszło nie tak i wystąpił jakiś wyjątek, którego nie obsłużyliśmy. Ok, tylko jak się dowiedzieć co się stało? Jednym ze sposobów jest oczywiście włączenie Debug Logów na danym użytkowniku i przejście przez proces raz jeszcze. Dojedziemy do powyższej strony ale w logach powinien się odłożyć błąd jaki leci na backendzie. Jednak nie zawsze jest to takie proste i oczywiste. Są przypadki, gdzie z pozoru wszystko jest ok, system rzuci wyjątkiem, wyświetli powyższy komunikat, jednak nie znajdziemy w logach nic, co by nam pomogło lub założenie logów na danego użytkownika nie będzie możliwe. Mieliśmy wielokrotnie zgłoszenia, że w systemie poleciał wyjątek, nie wiadomo jednak dokładnie gdzie i kiedy, a użytkownik wysyła nam jedynie powyższego screena. W takich sytuacjach bardzo pomocny jest pewien "trick", który wyświetla na Exception page opis błędu (exception message).
Jeżeli spojrzymy w domyślny Exception Page to będzie on wyglądał jakoś tak:
<apex:page showHeader="false" title="{!$Label.site.error2}" cache="false">
<apex:composition template="{!$Site.Template}">
<apex:define name="body">
<center>
<apex:panelGrid bgcolor="white" columns="1" style="align: center;">
<br/>
<br/>
<apex:panelGrid width="758" cellpadding="0" cellspacing="0" bgcolor="white" columns="1" styleClass="topPanelContainer">
<br/>
<apex:outputPanel layout="block" styleClass="topPanel">
<apex:panelGrid width="758" cellpadding="0" cellspacing="0" bgcolor="white" columns="3">
<apex:image url="{!URLFOR($Resource.SiteSamples, 'img/clock.png')}"/>
<apex:image url="{!URLFOR($Resource.SiteSamples, 'img/warning.png')}"/>
<apex:panelGroup >
<apex:outputText styleClass="title" value="{!$Label.site.error}">
<apex:param value="{!$Site.ErrorMessage}"/>
<!-- this parameter needs to be italic in the site.error label -->
</apex:outputText>
<br/>
<br/>
<apex:outputText escape="false" value=" {!$Label.site.get_in_touch}">
<apex:param value="mailto:{!HTMLENCODE($Site.AdminEmailAddress)}"/>
<apex:param value="{!$Label.site.email_us}"/>
</apex:outputText>
</apex:panelGroup>
</apex:panelGrid>
</apex:outputPanel>
<c:SitePoweredBy />
</apex:panelGrid>
<br/>
<apex:messages />
<br/>
</apex:panelGrid>
</center>
</apex:define>
</apex:composition>
</apex:page>
Nie ma tu nic interesującego, poza jedną linią. Jeżeli spojrzymy na linię numer 16. W tym miejscu przekazujemy parametr opisujący błąd. Widzimy tam <apex:param value="{!$Site.ErrorMessage}"/> czyli globalny obiekt Site oraz jego pole ErrorMessage. W tym miejscu wystarczy zamienić ErrorMessage na ErrorDescription i następnym razem kiedy ów strona nam się ukaże, zobaczymy więcej mówiący komunikat, który na pewno nie rozwiąże naszych problemów, ale w znaczącym stopniu pomoże namierzyć kod, który wywołuje błąd.
<!--Salesforce exception page modification to show error message-->
<apex:outputText styleClass="title" value="{!$Label.site.error}">
<apex:param value="{!$Site.ErrorDescription}"/>
<!-- this parameter needs to be italic in the site.error label -->
</apex:outputText>