Home Server
New Blog Posts: Merging Reports - Part 1 and Part 2

Putting More Information Into Error Page

edited October 2005 in Server
Hello

How can I get more information into my error page descendant?

I am inheriting from TrsWebErrorPage

I want to get the report parameters into the error page and at least a title

I think I may have to put all of this information into an Exception object
but I am hoping there is a better way than that!

Cheers

Paul

Comments

  • edited October 2005
    I also have another problem now

    When I use my webmodule within my web tier test application my error page is
    created and used

    However, when the actual webtier is used, its not used

    I still cannot debug the webtier directly

    Where in the webmodule do I need to put the line below

    wmMain.rsWebtier.ErrorPageClass := TSTCWebtierErrorPage;

    I have put it in the initialization section of the web module

    Cheers

    Paul


  • edited November 2005


    I would use the WebTier.OnCreate event


    Correct. Create a descendant of EWebTierError which is defined in
    rsExceptions.


    We use the Delphi WebDebugger as much as possible. To debug an ISAPI
    application or a ASP application, we use CodeSite and its TCP/IP extension -
    which enables an application to broadcast messages to the CodeSite
    dispatcher (either on the same machine or on another machine).



    --
    Nard Moseley
    Digital Metaphors Corporation
    http://www.digital-metaphors.com

    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited November 2005
    ok thanks Nard

    I will try this out

    I was not aware of there being a TCP extension for Codesite!

    Do you have any idea why I am getting the problem mentioned in my last post
    here? Where the exception page is not coming up from the webtier itself but
    does through my test app?


  • edited November 2005

    1. I think I recall that you have to have the professional version of
    CodeSite. You can check with their tech support.

    2. I do not know why that would occur. Make sure you are copying the new web
    app to the appropriate IIS directory - its easy to forget that last step.




    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited November 2005
    Hi Nard

    I have verified that and its fine????

    Cheers

    Paul

  • edited November 2005

    I created a simple test here that works with the demo WebDebug and ISAPI
    apps.

    1. I created a TMyWebErrorPage class that overrides the CreateErrorPage
    method

    lTemplate.SetVariable('message', '****Test Custom Error Page****' +
    ProcessMessage(aException.Message));


    2. Implemented the WebModule.OnCreate event-handler

    procedure TWebModule1.WebModuleCreate(Sender: TObject);
    begin
    rsWebTier1.ErrorPageClass := TmyWebErrorPage;
    end;

    3. Implemented the WebTier.AfterProcessRequest event to raise an exception

    procedure TWebModule1.rsWebTier1AfterProcessRequest(aSender,
    aContentProvider, aRequest: TObject; aResponse: String);
    begin
    raise EReportBuilderError.Create('Test Exception Handling');

    end;


    I used RB 9.03...




    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited November 2005
    What does processMessage do Nard?

    I am already raising my custom exception, but its being raised in my process
    request code

    See below

    PROCEDURE TwmMain.FillParameters(CONST
    objParameters:TSTCReportParameters;CONST strQuery,strContent:String;CONST
    objParametersList:TStringList);
    var
    objParameter: TSTCReportParameter;
    cnt: Integer;
    arrTemp:strArray;
    BEGIN
    TrsWebRequestParser.ParseContent(strQuery,objParametersList);
    TrsWebRequestParser.ParseContent(strContent,objParametersList);

    FOR cnt:=0 TO objParametersList.Count-1 DO
    BEGIN
    objParameter:=TSTCReportParameter(objParameters.NewItem);

    arrTemp:=Split(False,objParametersList[cnt],'=');

    TRY
    objParameter.Name:=arrTemp[0];
    objParameter.Value:=arrTemp[1];
    EXCEPT
    objParameter.Value:='';
    END;
    END;
    END;

    FUNCTION TwmMain.ExtractConnectionString(CONST
    objParameters:TSTCReportParameters):String;
    VAR
    nCustomerID: Integer;
    BEGIN
    IF objParameters.ParamExists('ConnectionString') THEN
    Result:=objParameters.AsObject('ConnectionString').Value
    ELSE
    BEGIN
    nCustomerID:=objParameters.AsInteger('CustomerID');
    Result:=ConnectionStringForCustomer(nCustomerID,cInstallDir+'STCREportsWebtier.ini');
    END;
    END;

    PROCEDURE TwmMain.FillDefaultSessionParams(CONST
    objParameters:TSTCReportPArameters;CONST objWebRequest:TrsWebRequest);
    VAR strContent:String;
    objStringList: TStringList;
    BEGIN
    TRY
    strContent:=objParameters.AsString('Content');
    EXCEPT
    strContent:='';
    END;
    objWebRequest.SessionParameters['AdditionalParams'].Value:=objParameters.ToXML;
    objWebRequest.SessionParameters['ConnectionString'].Value:=ExtractConnectionString(objParameters);
    objWebRequest.SessionParameters['ReportID'].Value :=
    objParameters.AsInteger('ReportID');

    IF strContent='' THEN
    objWebRequest.ContentType:='Viewer'
    ELSE
    objWebRequest.ContentType:=strContent;

    objWebRequest.ReportName:='\'+RBSectionName(TReportID(objWebRequest.SessionParameters['ReportID'].Value))+'\'+RBReportName(TReportID(objWebRequest.SessionParameters['ReportID'].Value));
    objWebRequest.VolumeName:='STC Reports';
    END;

    FUNCTION TwmMain.ProcessRequest(CONST
    strQueryString,strContent:String):String;
    var
    nReportID: Integer;
    strTitle: STRING;
    objTempParameters: TSTCReportParameters;
    objWebRequest: TrsWebRequest;
    objParametersList:TStringList;
    begin
    wmMain.rsWebTier.ErrorPageClass:=TSTCWebTierErrorPage;
    TRY
    objParametersList:=TStringList.Create;
    TRY
    objTempParameters:=TSTCReportParameters.Create;
    TRY
    FillParameters(objTempParameters,strQueryString,strContent,objParametersList);
    TRY

    nReportID:=objTempParameters.AsInteger('ReportID');

    objWebRequest:=rsWebTier.CreateWebRequest(objParametersList,strContent);

    FillDefaultSessionParams(objTempParameters,objWebRequest);

    Result:=rsWebTier.ProcessWebRequest(objWebRequest);
    FINALLY
    objWebRequest.Free;
    END;
    FINALLY
    FreeAndNil(objTempParameters);
    END;
    FINALLY
    FreeAndNil(objParametersList);
    END;
    EXCEPT
    ON E:Exception DO
    Result:=rsWebTier.HandleException(objWebRequest,
    EWebtierException.Create('Title','Additonal Info',E.Message));
    END;
    end;

  • edited November 2005

    1. Rather than

    wmMain.rsWebTier.ErrorPageClass:=TSTCWebTierErrorPage;

    try

    rsWebTier.ErrorPageClass := TSTCWebTierErrorPage;

    2. Try moving the code in 1 above to the WebModule.OnCreate event. That is
    what I did in my example.

    3. I just copied that method from the ancestor and it was calling
    ProcessMessage to perform some formatting. Its not relevant to the example.
    You can return any valid html page.






    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited November 2005
    Hi Nard

    I am getting a problem here

    When I step into my code I expect the classname of E to by EWebtierException
    but it is EClientError?

    My code is below

    class function TSTCWebTierErrorPage.CreateErrorPage(
    aException: Exception): String;
    VAR
    objWebTierException:EWebTierException ABSOLUTE aException;
    strHTML: STRING;
    begin
    strHTML:=cErrorHTML;
    strHTML:=StringReplace(strHTML,'%Message%',objWebTierException.Message,[rfReplaceAll,rfIgnoreCase]);
    strHTML:=StringReplace(strHTML,'%Title%',objWebTierException.Title,[rfReplaceAll,rfIgnoreCase]);
    strHTML:=StringReplace(strHTML,'%AdditionalInfo%',objWebTierException.AdditionalInfo,[rfReplaceAll,rfIgnoreCase]);

    Result:=strHTML;
    end;


    FUNCTION TwmMain.ProcessRequest(CONST
    strQueryString,strContent:String):String;
    var
    nReportID: Integer;
    strTitle: STRING;
    objTempParameters: TSTCReportParameters;
    objWebRequest: TrsWebRequest;
    objParametersList:TStringList;
    begin
    wmMain.rsWebTier.ErrorPageClass:=TSTCWebTierErrorPage;
    TRY
    objParametersList:=TStringList.Create;
    TRY
    objTempParameters:=TSTCReportParameters.Create;
    TRY
    FillParameters(objTempParameters,strQueryString,strContent,objParametersList);
    TRY

    nReportID:=objTempParameters.AsInteger('ReportID');

    objWebRequest:=rsWebTier.CreateWebRequest(objParametersList,strContent);

    FillDefaultSessionParams(objTempParameters,objWebRequest);

    Result:=rsWebTier.ProcessWebRequest(objWebRequest);
    FINALLY
    objWebRequest.Free;
    END;
    FINALLY
    FreeAndNil(objTempParameters);
    END;
    FINALLY
    FreeAndNil(objParametersList);
    END;
    EXCEPT
    ON E:Exception DO
    Result:=rsWebTier.HandleException(objWebRequest,
    EWebtierException.Create(RBReportName(TReportID(nReportID)),objTempParameters.AsCommaText,E.Message));
    END;
    end;

  • edited November 2005

    The custom error page class will be called for all exceptions that occur. Do
    not assume that it is of a particular Exception type. Instead check the type
    inside you method:

    Example:

    if (aException is EWebTierException) then
    {custom code here}
    else
    {other custom code here}




    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited November 2005
    Hi Nard

    I dont quite get this - my code swallows any exception raised and re raises
    it as a EWebTierException

    How can a EClientError get through this?

    One of the ones I am trying out is the classic cannot connect to server

    TRY
    .................
    All code here
    EXCEPT
    ON E:Exception DO
    RAISE
    EWebtierException.Create(RBReportName(TReportID(nReportID)),objTempParameters.AsCommaText,E.Message);
    END;

    Cheers

    Paul

  • edited November 2005

    To customize an error page, you need to create a custom error page class -
    as we have dicussed.

    The WebTier catches all exceptions and calls its HandleException method.
    Thus your attempts to trap errors outside of the webtier will not work.


    try
    {}

    except
    on E: Exception do
    Result := HandleException(CurrentRequest, E);

    end;


    The HandleException method uses the ErrorPageClass to generate the html
    error page. It basically looks like this....



    function TrsWebTier.HandleException(aRequest: TrsWebRequest; E: Exception):
    String;
    begin

    Result := GetErrorPageClass.CreateErrorPage(E);
    gWebLog.WriteException(E, aRequest.RequestID, aRequest.SessionID);



    end;










    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited November 2005
    Hi Nard

    I have created this class and it works as discussed

    My problem is that I specifically raise an EWebTierException - because I
    want 2 more pieces of information, however the exception type is not
    EWebTier Exception

    I have modified the code to raise an EWebTierException it still does not
    work!

    Cheers

    Paul

  • edited November 2005
    I need to get custom information into my error page class - hence why we
    spoke about creating a custom error exception

    Am not sure what you mean by me trying to trap errors outside of the webtier


  • edited November 2005

    Where in your code are you raising the exception?


    If you want to create a simple test case and email to
    support@digital-metaphors.com we can look at it here.






    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • edited November 2005
    ok Nard I have sent you an example

  • edited November 2005
    > ok Nard I have sent you an example

    I looked at the example you sent and it is exactly the situation that I
    tried to describe before. Sorry if I was not clear before. I will give it
    another try.

    The problem here is that once you call WebTier.ProcessWebRequest, any
    exception that occurs will be handled internally by the web tier and will
    result in an HTML Error Page being returned.

    Your code looks something like this:

    try
    Result := myWebTier.ProcessWebRequest(myWebRequest);

    except
    on E: Exception do
    raise myWebException.Create('Custom Title', Custom Info', E);

    end;


    Your except block will never fired, because the WebTier will catch it first.


    If you want to include custom information in the HTML Error Page you will
    have to do it by some other means. Perhaps initialize some global variables
    prior to calling WebTier.ProcessRequest. Then use the global variables in
    the error page class.

    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
This discussion has been closed.