Giter Club home page Giter Club logo

Comments (33)

silvioprog avatar silvioprog commented on July 19, 2024

Fixed (c8f0ceb).

To test it, implement:

unit Brokers;

{$mode objfpc}{$H+}

interface

uses
  BrookFCLCGIBroker, BrookUtils;

implementation

initialization
  BrookSettings.Page404 :=
    '<html><head><title>Page not found</title></head><body>' +
    '<h1>404 - Page not found</h1></body></html>';

end.

And, to causing the error:

type
  TMyAction = class(TBrookAction)
  public
    procedure Get; override;
  end;

implementation

procedure TMyAction.Get;
begin
  Error('Fail');
end;

You will got a default FCL-Web content, sush as:

: ERROR

The application encountered the following error:
Error: TMyAction: Fail
Stack trace:
$00436821 TBROOKACTION__ERROR, line 500 of C:/repository/git/brookframework-silvioprog/core/brookaction.pas
$00411EF6 TMYACTION__GET, line 20 of unit1.pas
$00436478 TBROOKACTION__REQUEST, line 401 of C:/repository/git/brookframework-silvioprog/core/brookaction.pas
$00436298 TBROOKACTION__DOREQUEST, line 338 of C:/repository/git/brookframework-silvioprog/core/brookaction.pas
$0042D985 TBROOKROUTER__DOEXECUTEACTION, line 326 of C:/repository/git/brookframework-silvioprog/core/brookrouter.pas
$0042E3CE TBROOKROUTER__ROUTE, line 606 of C:/repository/git/brookframework-silvioprog/core/brookrouter.pas
$0042CA77 TBROOKCGIHANDLER__HANDLEREQUEST, line 258 of C:/repository/git/brookframework-silvioprog/brokers/brookfclcgibroker.pas
$004323E1
$0042C1E4 TBROOKAPPLICATION__RUN, line 108 of C:/repository/git/brookframework-silvioprog/brokers/brookfclcgibroker.pas
$00401727 main, line 9 of cgi1.lpr
Notify: webmaster: webmaster@localhost

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

I don't get the backtrace, the application is still terminated on error. Note that I'm using FastCGI.

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

I'll test it. Please send me a small demo using fpWeb with FastCGI.

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

Done: https://dl.dropbox.com/u/22124591/fastcgiexceptiontest.zip

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Fixed (15f0141). Please test if it's OK.

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

I can't merge this change automatically to my fork. Maybe you could?

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Hm... I have not found an option for that. :/ You can delete the project and fork again.

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

Ah..I see that you've given write access for me, that's why. I'll do direct push from now as the way to manually merge involve some git commands I never use and must be done from terminal.

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

OK, everything works now. I guess you need to document that in order the stack trace to appear, BrookSettings.PageXXX must be empty string.

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

I fully agree. So, my friend who translates from Portuguese to English is on vacation and returns just in February, could you help me on this?

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

Which source holds the documentation? Or where should I add this documentation?

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

You can edit it directly in the .pas:

1 - https://github.com/silvioprog/brookframework/blob/master/core/brookutils.pas#L49

2 - https://github.com/silvioprog/brookframework/blob/master/core/brookutils.pas#L52

And after, you or I re-generate the HTML via PasDoc to upload it to the site. :)

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Nice?:

{ Set the 500 HTML page. It can be a HTML string, a file pack,
  a JSON string, etc. If this property is empty, the Brook use
  the default error page of the FCL-Web. }

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

I'd add:

the (or then?) Brook use the default error page of the FCL-Web, which may contain stack trace.

But reading about it... I'm thinking about a setting or property to allow stack trace to appear regardless the Page404 or Page500 is filled or not. Guess it would be easy to implement, I'll try something tonight (I have no git at office).

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

This would be an interesting feature.
I use my own 4xx/5xx pages, but would like to enable or disable the stack trace (to discover bugs without run the CGIs in the terminal).

from brookframework.

mdbs99 avatar mdbs99 commented on July 19, 2024

This new feature is very important. I think a property is sufficient as leledumbo said.

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

Implemented: 81492b2

from brookframework.

mdbs99 avatar mdbs99 commented on July 19, 2024

So, closed.

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

I think I'll have to change this commit, because the user (programmer) may be using purely JSON, and it would show an error message in HTML into JSON content, and this would be a problem. :/
I have not had time to test this change because I'm on my girlfriend's PC, but I'll test as soon as possible.
I think that just adding the stack trace into the error message would meet everyone (JSON users, HTML users or both).

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Another interesting option would be to add an additional input format, an example of use would be:

  BrookSettings.Page500 :=
    '<html><head><title>Internal server error</title></head><body>' +
    '<h1>500 - Internal server error</h1>' +
    '<p style="color: red;" >Error: %s</p>' +
    '<p style="color: red;" >Stack trace: %s</p></body></html>';

I.e.: The first %s is the error message, and the last %s is the stack trace, so it would be used in JSON error too, e.g.:

BrookSettings.Page500 := '{ "error": "%s", "trace": "%s" }';

Nice?

from brookframework.

mdbs99 avatar mdbs99 commented on July 19, 2024

Maybe:

  BrookSettings.Page500 :=
    '<html><head><title>Internal server error</title></head><body>' +
    '<h1>500 - Internal server error</h1>' +
    '<p style="color: red;" >Error: #ERROR#</p>' +
    '<p style="color: red;" >Stack trace: #STACKTRACE#</p></body></html>';

and

BrookSettings.Page500 := '{ "error": "#ERROR#", "trace": "#STACKTRACE#" }';

So, using "macros". The user can use whatever information he want.

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Or, using JTemplate's syntax::

BrookSettings.Page500 :=
    '<html><head><title>Internal server error</title></head><body>' +
    '<h1>500 - Internal server error</h1>' +
    '<p style="color: red;" >Error: @error</p>' +
    '<p style="color: red;" >Stack trace: @trace</p></body></html>';
BrookSettings.Page500 := '{ "error": "@error", "trace": "@trace" }';

Good?

from brookframework.

mdbs99 avatar mdbs99 commented on July 19, 2024

For me is the same thing. The most import is the idea, not the implementation... in this case, of course.

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

If you replace with a SysUtils.Format() style function, it might inadequate (because the search is done by index), but with JTemplate style it's better (search by name).
A bit OOT: Why JTemplate instead of FPTemplate / TTemplateParser?

from brookframework.

mdbs99 avatar mdbs99 commented on July 19, 2024

If you replace with a SysUtils.Format() style function, it might inadequate (because the search is done by index),
but with JTemplate style it's better (search by name).

Because this I suggested to use 'macros' (but doesn't matter which engine will be used).

A bit OOT: Why JTemplate instead of FPTemplate / TTemplateParser?

I do not know.

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

A bit OOT: Why JTemplate instead of FPTemplate / TTemplateParser?

The question is for Silvio actually :3

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

About the 'macros', there are great chance to use the JTemplate sintax, because it is very simple and straightforward.

About JTpl X FPTpl X TplParser: IMHO, I think the JTemplate more fast, sleek and intuitive, and it offers a native support for JSON and HTML.

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Implemented in "master" branch (the new "tmp" changes will be implemented in "working" branch): 57921e5.

It is implemented using SysUtils.Format(), but in the future it can be implemented using macros.

So, for this configuration:

(...)
  BrookSettings.Page500 :=
    '<html><head><title>Internal server error</title></head><body>' +
    '<h1>500 - Internal server error</h1>' +
    '<p style="color: red;" >Error: %s</p>' +
    '<p style="color: red;" >Trace: %s</p></body></html>';
(...)

The result is:

<html><head><title>Internal server error</title></head><body><h1>500 - Internal server error</h1><p style="color: red;" >Error: TMyAction: Fail</p><p style="color: red;" >Trace:   $004369F1  TBROOKACTION__ERROR,  line 500 of C:/repository/git/brookframework-silvioprog/core/brookaction.pas<br />  $00411F06  TMYACTION__GET,  line 20 of unit1.pas<br />  $00436648  TBROOKACTION__REQUEST,  line 401 of C:/repository/git/brookframework-silvioprog/core/brookaction.pas<br />  $00436468  TBROOKACTION__DOREQUEST,  line 338 of C:/repository/git/brookframework-silvioprog/core/brookaction.pas<br />  $0042DB55  TBROOKROUTER__DOEXECUTEACTION,  line 326 of C:/repository/git/brookframework-silvioprog/core/brookrouter.pas<br />  $0042E59E  TBROOKROUTER__ROUTE,  line 606 of C:/repository/git/brookframework-silvioprog/core/brookrouter.pas<br />  $0042CA87  TBROOKCGIHANDLER__HANDLEREQUEST,  line 258 of C:/repository/git/brookframework-silvioprog/brokers/brookfclcgibroker.pas<br />  $004325B1<br />  $0042C1F4  TBROOKAPPLICATION__RUN,  line 108 of C:/repository/git/brookframework-silvioprog/brokers/brookfclcgibroker.pas<br />  $00401727  main,  line 9 of project1.lpr<br /></p></body></html>

And for this:

(...)
  BrookSettings.ContentType := BROOK_HTTP_CONTENT_TYPE_APP_JSON;
(...)
  BrookSettings.Page500 := '{ "error": "%s", "trace": "%s" }';  
(...)

The result is:

{ "error": "TMyAction: Fail", "trace": "  $00436A01  TBROOKACTION__ERROR,  line 500 of C:\/repository\/git\/brookframework-silvioprog\/core\/brookaction.pas\r\n  $00411F16  TMYACTION__GET,  line 20 of unit1.pas\r\n  $00436658  TBROOKACTION__REQUEST,  line 401 of C:\/repository\/git\/brookframework-silvioprog\/core\/brookaction.pas\r\n  $00436478  TBROOKACTION__DOREQUEST,  line 338 of C:\/repository\/git\/brookframework-silvioprog\/core\/brookaction.pas\r\n  $0042DB65  TBROOKROUTER__DOEXECUTEACTION,  line 326 of C:\/repository\/git\/brookframework-silvioprog\/core\/brookrouter.pas\r\n  $0042E5AE  TBROOKROUTER__ROUTE,  line 606 of C:\/repository\/git\/brookframework-silvioprog\/core\/brookrouter.pas\r\n  $0042CA97  TBROOKCGIHANDLER__HANDLEREQUEST,  line 258 of C:\/repository\/git\/brookframework-silvioprog\/brokers\/brookfclcgibroker.pas\r\n  $004325C1\r\n  $0042C204  TBROOKAPPLICATION__RUN,  line 108 of C:\/repository\/git\/brookframework-silvioprog\/brokers\/brookfclcgibroker.pas\r\n  $00401727  main,  line 9 of project1.lpr\r\n" }

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

Hmm.. since SysUtils.Format is used, if the user doesn't supply the required %s (or if one supplies another %), it will cause a runtime error. Then how NOT to get the stack trace?

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

You can omit the %s, e.g.:

initialization
  BrookSettings.Page404 :=
    '<html><head><title>Page not found</title></head><body>' +
    '<h1>404 - Page not found</h1></body></html>';
  BrookSettings.Page500 :=
    '<html><head><title>Internal server error</title></head><body>' +
    '<h1>500 - Internal server error</h1>' +
    '<p style="color: red;" >Error: %s</p></body></html>'; 

The result:

<html><head><title>Internal server error</title></head><body><h1>500 - Internal server error</h1><p style="color: red;" >Error: TMyAction: Fail</p></body></html>

Omitting both %s:

  BrookSettings.Page500 :=
    '<html><head><title>Internal server error</title></head><body>' +
    '<h1>500 - Internal server error</h1>' +
    '<p style="color: red;" >Oh God, why? :(</p></body></html>'; 

Result:

<html><head><title>Internal server error</title></head><body><h1>500 - Internal server error</h1><p style="color: red;" >Oh God, why? :(</p></body></html>

But it will be implemented with macros soon. :)

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

So, an implementation for macro support:

procedure TBrookCGIHandler.ShowRequestException(R: TResponse; E: Exception);
var
  VStr: TStrings;
  VHandled: Boolean = False;
begin
  if R.ContentSent then
    Exit;
  if Assigned(BrookSettings.OnError) then
  begin
    BrookSettings.OnError(R, E, VHandled);
    if VHandled then
      Exit;
  end;
  if Assigned(OnShowRequestException) then
  begin
    OnShowRequestException(R, E, VHandled);
    if VHandled then
      Exit;
  end;
  if RedirectOnError and not R.HeadersSent then
  begin
    R.SendRedirect(Format(RedirectOnErrorURL, [HTTPEncode(E.Message)]));
    R.SendContent;
    Exit;
  end;
  if (BrookSettings.Page404 <> ES) and (E is EBrookHTTP404) and
    (not R.HeadersSent) then
  begin
    R.Code := BROOK_HTTP_STATUS_CODE_NOT_FOUND;
    R.CodeText := BROOK_HTTP_REASON_PHRASE_NOT_FOUND;
    R.ContentType := FormatContentType;
    if FileExists(BrookSettings.Page404) then
      R.Contents.LoadFromFile(BrookSettings.Page404)
    else
      R.Content := BrookSettings.Page404;
    R.Content := Format(R.Content, [ApplicationURL]);
    R.SendContent;
    Exit;
  end;
  if (BrookSettings.Page500 <> ES) and (not R.HeadersSent) then
  begin
    R.Code := BROOK_HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR;
    R.CodeText := 'Application error ' + E.ClassName;
    R.ContentType := FormatContentType;
    if FileExists(BrookSettings.Page500) then
    begin
      R.Contents.LoadFromFile(BrookSettings.Page500);
      R.Content := StringsReplace(R.Content, ['@error', '@trace'],
        [E.Message, BrookDumpStack], [rfIgnoreCase, rfReplaceAll]);
    end
    else
      if BrookSettings.ContentType = BROOK_HTTP_CONTENT_TYPE_APP_JSON then
        R.Content := StringsReplace(BrookSettings.Page500, ['@error', '@trace'],
          [StringToJSONString(E.Message), StringToJSONString(BrookDumpStack(LE))],
          [rfIgnoreCase, rfReplaceAll])
      else
        R.Content := StringsReplace(BrookSettings.Page500, ['@error', '@trace'],
          [E.Message, BrookDumpStack], [rfIgnoreCase, rfReplaceAll]);
    R.SendContent;
    Exit;
  end;
  if (R.ContentType = BROOK_HTTP_CONTENT_TYPE_TEXT_HTML) or
    (BrookSettings.ContentType = BROOK_HTTP_CONTENT_TYPE_TEXT_HTML) then
  begin
    VStr := TStringList.Create;
    try
      ExceptionToHTML(VStr, E, Title, Email, Administrator);
      R.Content := VStr.Text;
      R.SendContent;
    finally
      VStr.Free;
    end;
  end;
end;

Using StrUtils.StringsReplace() sounds interesting?

from brookframework.

leledumbo avatar leledumbo commented on July 19, 2024

That's better, since there will be only 2 placeholders, I think StrUtils.StringsReplace is fine.

from brookframework.

silvioprog avatar silvioprog commented on July 19, 2024

Done in branch "working".
1 - 379f7db
2 - a6659af
3 - 6138c02

from brookframework.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.