Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

making default reponse text, with optional formatting to be passed #1905

Closed
wants to merge 1 commit into from

Conversation

ProjitB
Copy link

@ProjitB ProjitB commented Aug 5, 2020

The default error handling should not return html text. Sanic itself can be run as a headless server just for API consumption (ex. CLIs). It would make sense for errors to be propagated with the text they are originally supplied with rather than with surround html tags. While custom error handling is of course possible, I do believe that this should be the default behavior.

Additionally, custom formatting can be passed as a string as before, just pass {{body}}:
f"<!DOCTYPE html><meta charset=UTF-8><title>{title}</title><style>{TRACEBACK_STYLE}</style>\n <h1>⚠️ {title}</h1><p>{{body}}\n {_render_traceback_html(request, exception)}"

Copy link
Member

@ahopkins ahopkins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First, thank you so much for adding this. I have been myself meaning to make this change for some time now.

With that said, I do not want to just remove the HTML page as it does have value. Instead, I think it should be configurable with three options:

  1. HTML page (as it was)
  2. Plain text
  3. JSON document

For now, I do not want to change the existing behavior. So, I would suggest leaving the HTML as default, with an opt in for the other styles. After the next LTS, we can debate which one should be default.

@Tronic
Copy link
Member

Tronic commented Aug 5, 2020

A custom error handling middleware is probably the best way to go for machine-readable error messages. Different APIs require vastly different error messages ranging from empty documents (only status code) to plain text message and JSON in various formats.

I think that changing this properly needs more work than simply this patch, which would still show internal server errors as HTML if I am not mistaken (tracebacks etc. are HTML formatted).

@ProjitB
Copy link
Author

ProjitB commented Aug 5, 2020

@ahopkins thank you for your comments. I agree with the proposal of having a configurable option. It should be something which is configurable by a user though right? I couldn't see a clean way in the current design to pass user preferences til that point (shouldn't be a global config for the reasons @Tronic mentioned..of different APIs consuming different types of errors).

@Tronic I could extend it to the other responses, but I think a configurable option throughout would make sense.

To handle the multiple responses, should a parameter be added to SanicException?
Also, what would be a clean way of getting the plain text response without modifying the code in the current released version? The exceptions like raise ServerError("<some error>") were being consumed directly before. Upgrading Sanic versions broke that compatibility due to the new html formatted errors.

@Tronic
Copy link
Member

Tronic commented Aug 6, 2020

Error handling middleware has the advantage that it can also contain the logic for determining which type of response is required. Some apps may determine this by request content-type, others might use path such as /api/ or specific blueprint for custom style responses, some might even need XML or other very custom responses. Overall, this appears to vary a lot from one webapp to another.

@ahopkins
Copy link
Member

ahopkins commented Aug 6, 2020

Clearly exception handlers and middleware are the recommended methodology in a production server. However, when prototyping something or getting something started, it is not convenient and often annoying that the exceptions come back in HTML format.

I am not suggesting that we offer full blown solutions since there will clearly need to be considerations that the individual developer needs to make. But, having text and JSON options will be considerably more user-friendly than the current state.

Furthermore, I disagree and think it absolutely should be globally defined. We are talking about the default fallback handler.

if request.app.config.DEFAULT_ERROR_FORMAT == "text":
    resp = text(...)
elif request.app.config.DEFAULT_ERROR_FORMAT == "json":
    resp = json(...)
else:
    resp = html(...)

@myusko
Copy link
Contributor

myusko commented Aug 17, 2020

Yes, agree with @ahopkins that's the default error output should be defined globally, and also do we consider dynamic changing of default error output?

@ahopkins
Copy link
Member

ahopkins commented Aug 17, 2020

Yes, agree with @ahopkins that's the default error output should be defined globally, and also do we consider dynamic changing of default error output?

I am generally not a fan of this. Or at least trying to support this from within Sanic. The problem is that running services like Sanic generally will be scaled horizontally. Syncing config values is tricky and undoubtedly would need another service to achieve that.

HOWEVER, I am working on a new user guide with tutorials. A good place to put something like this would be there as a "how could you achieve this" type of reference material.

@ashleysommer
Copy link
Member

ashleysommer commented Sep 16, 2020

My opinion on this, with highest preference first:

  1. Leave it as-is. The default exception handler will output HTML formatted errors, and users can add custom handlers if they want other formats
  2. As @ahopkins suggested above, have a config variable like app.config.DEFAULT_ERROR_FORMAT = "text" but keep "html" the default fallback.

@ahopkins
Copy link
Member

Closing in favor of #1937

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants