Root > How to... > ...return exception to custom web API?

...return exception to custom web API?

Previous pageReturn to chapter overviewNext page   

Normally you would use a HTML (web) dialog in your ISAPI, CGI, IntraWeb, etc. application. This dialog is intended to display failure to the user in a web browser. It can also be used if your web API uses HTTP status code to determinate failures. Web dialog can also work with simple JSON and XML templates. If that is what you want to do - just set up web dialog settings.

 

Alternatively, you may want to implement your own custom web dialog for any other usage cases. You can do this by overriding a default web dialog class.

 

1. Set dialog to "WEB" in your EurekaLog project options;
2. Use this customization code:

 

uses
  EDialog,      // for RegisterDialogClassFirst

  EEncoding,    // for TMarkupLanguage (only if you override a .GetTextType)
  EDialogISAPI, // for TWebDialog - you can replace this unit with 

                // EDialogCGI or EDialogIntraWeb, 

                // depending on what you are using in your application
 

  ECallStack,   // optional, only for example below
  EDebugInfo,   // optional, only for example below

  EJSON;        // optional, only for example below
 
type
  TWebDialog = class(EDialogISAPI.TWebDialog)
  protected

    // You don't need to override every method

    // This is only an example

    // Delete method override if you want a default behavior

    // Override only if you need to customize
    function GetText(const AContentType: String): Stringoverride;
    function GetTextType: TMarkupLanguage; override;

    function GetWebErrorCode: Integer; override;

    function GetContentType: Stringoverride;
    function GetHeaders(const AContentType: String

      const ARawTextLen, ATextLen: Integer): RawByteString; override;

  end;
 
{ TWebDialog }
 

// Returns actual page content
function TWebDialog.GetText(const AContentType: String): String;

 

  // This is just an example

  // You may remove it if you don't need it
  function CallStack2JSONArray: Variant;
  var
    Stack: TEurekaBaseStackList;
    TID: Cardinal;
    Arr: array of String;
    X, C: Integer;
  begin
    Stack := CallStack;
    Result := Unassigned;
 
    if (Stack = nilor (Stack.Count = 0) then
      Exit;
 

    // Copy into Arr first call stack from Stack

    // First call stack is the call stack for exception
    TID := Stack.Item[0].ThreadID;
    SetLength(Arr, Stack.Count);
    C := 0;
 
    for X := 0 to Stack.Count - 1 do
    begin
      if Stack.Item[X].ThreadID <> TID then
        Break;
      Arr[C] := LocationToStr(Stack.Item[X].Location);
      Inc(C);
    end;
    SetLength(Arr, C);
 

    // Once Arr is ready - convert it to variant array
    Result := VarArrayCreate([0, C - 1], varString);
    for X := 0 to C - 1 do
      Result[X] := Arr[X];
  end;

 
begin
  // FixNames/FixValues are for compatibility with very old compilers, 

  // you may remove these wrappers for almost all IDEs
  Result := JSON(
    FixNames(['error''class''message''id', 'callstack']),
    FixValues([1, ExceptionInfo.ExceptionClass, ExceptionMessage, ExceptionInfo.BugIDStr,

               CallStack2JSONArray]));
 
  // Alternatively, you may do:
  // Result := Options.HTMLLayout;
  // and make StringReplace for tags, replacing tags with actual info values
end;

 

// This value is mostly used to extract codepage

// from hard-coded tags inside page content

// returned by .GetText method.

function TWebDialog.GetTextType: TMarkupLanguage; 
begin
  Result := mlJSON;
  // Default is mlHTML, also possible mlXML

end;
 

// Returns HTTP status code

function TWebDialog.GetWebErrorCode: Integer;
begin
  Result := 200; 

  // Alternative common value is 500

  // Default is Result := Options.WebErrorCode;
end;

 

// Returns HTTP Context Type

function TWebDialog.GetContentType: String;
begin
  Result := 'application/json';
  // Default is similar to 'text/html; charset=UTF-8'

end;
 

// Returns HTTP headers
function TWebDialog.GetHeaders(const AContentType: String
  const ARawTextLen, ATextLen: Integer): RawByteString;
begin
  Result := AnsiString(Format(
    'Status: %d %s'#13#10 +            
    'Content-Type: %s'#13#10 +        
    'Content-Length: %d'#13#10#13#10
    [WebErrorCode, ExceptionInfo.ExceptionMessage, AContentType, ARawTextLen]));
end;

 
initialization
  RegisterDialogClassFirst(TWebDialog); // override default web dialog with our custom dialog
end.

 

This code will replace default web dialog with your own implementation. You can do anything you like in your own code.

 

 

See also:

WEB dialog for general description of web dialog's type



Send feedback... Build date: 2019-09-24
Last edited: 2019-06-12
PRIVACY STATEMENT
The documentation team uses the feedback submitted to improve the EurekaLog documentation. We do not use your e-mail address for any other purpose. We will remove your e-mail address from our system after the issue you are reporting has been resolved. While we are working to resolve this issue, we may send you an e-mail message to request more information about your feedback. After the issues have been addressed, we may send you an email message to let you know that your feedback has been addressed.


Permanent link to this article: https://www.eurekalog.com/help/eurekalog/how_to_report_custom_web_api.php