Git Product home page Git Product logo

Comments (12)

malcolmsparks avatar malcolmsparks commented on September 27, 2024

Accepted

from yada.

malcolmsparks avatar malcolmsparks commented on September 27, 2024

I did check that this worked as expected:

["/500" (resource
               {:methods {:get {:produces "text/html"
                                :response (fn [ctx] (throw (new Exception "Ooh!")))}}
                :responses {500 {:produces "text/plain"
                                 :response (fn [ctx] "Error, but I'm OK")}}}
               )]

Is this enough for your purposes?

from yada.

shmish111 avatar shmish111 commented on September 27, 2024

Ah-ha! I think I was trying to use :responses within the :method my
apologies. This is exactly what I need. The only thing I would add though
is that for an HTTP server, a dumbed down error response might be required
globally. For a public API you don't really want to expose information
about the server that can come from a stack trace, I know yada tries to
avoid this type of global requirement but shouldn't this be a special case?
Or alternatively the default error handler should not send back stack
traces...

On Mon, Feb 8, 2016 at 4:40 PM, Malcolm Sparks [email protected]
wrote:

I did check that this worked as expected:

["/500" (resource
{:methods {:get {:produces "text/html"
:response (fn [ctx](throw %28new Exception)))}}
:responses {500 {:produces "text/plain"
:response (fn [ctx] "Error, but I'm OK")}}}
)]

Is this enough for your purposes?


Reply to this email directly or view it on GitHub
#55 (comment).

from yada.

malcolmsparks avatar malcolmsparks commented on September 27, 2024

It might be useful to be able to put :responses inside :method.

I'd yada to do the right thing in both dev and prod cases, but without requiring a configuration step (the way that pedestal needs a bootstrap config).

Perhaps an environment variable could be used in prod which yada's handler could pick up. I don't really want to go down the route of giving handler's options again. Eventually I hope that the default exceptions are really useful for developers (not just stack traces, but an entire story of the request and suggestions of how to fix the issue). It tends to be in prod that you get to set environment variables.

Have you got any further thoughts on this strategy?

from yada.

shmish111 avatar shmish111 commented on September 27, 2024

not really, it is really dev vs prod for the default handler. I just think that it's too easy not deploy this error handling to prod and not define a 500.

from yada.

jstaffans avatar jstaffans commented on September 27, 2024

For me, the example by @malcolmsparks above only works with instances of ExceptionInfo, ie something thrown using ex-info, not other Throwables. Using yada 1.1.6.

from yada.

malcolmsparks avatar malcolmsparks commented on September 27, 2024

Ah, in that case this is an issue - let's keep it open

from yada.

jstaffans avatar jstaffans commented on September 27, 2024

To be more specific, the example above doesn't work for :post methods:

  (yada/yada
   (yada/resource
    {:methods
     {:post {:consumes "application/json"
             :produces "text/plain"
             :response (λ [ctx] (throw (Exception. "Oh!")))}}
     :responses
     {500 {:produces "text/plain"
           :response (λ [ctx] "Internal error")}}}))

-> the "Internal error" is not shown, instead you get the full stacktrace.

from yada.

naartjie avatar naartjie commented on September 27, 2024

Today I was googling for yada exception handling and I clicked through on one of the links:

screen shot 2016-08-19 at 18 25 29

Once our API's/HTTP servers/whatever it it that we're developing are public facing, it's desirable to put a facade on our oversights (i.e. a nice "oops, we made a boo boo" page), and so I think it would make sense to have a generic server error response. I understand this is WIP, which is great.

For the time being, is using :responses something which can be used in the interim, and simply walking the tree that is my bidi routes, and inserting my default error handler for all resources which don't already have one defined?

Thanks a lot for a great library.

from yada.

malcolmsparks avatar malcolmsparks commented on September 27, 2024

Yes, that's exactly the purpose of status responses:
https://juxt.pro/yada/manual/index.html#status-responses

The code in yada that supports this feature is somewhat of a placeholder,
and if you have any particular requirements that aren't possible yet I'd be
very happy to provide improvements - let me know what you need.

Malcolm Sparks
Director

Email: [email protected]
Web: https://juxt.pro

JUXT LTD.
Software Consulting, Delivery, Training

On 19 August 2016 at 17:38, Marcin Jekot [email protected] wrote:

Today I was googling for yada exception handling and I clicked through on
one of the links:

[image: screen shot 2016-08-19 at 18 25 29]
https://cloud.githubusercontent.com/assets/514563/17816695/d4001bbe-663a-11e6-972f-75dc60c696c4.png

Once our API's/HTTP servers/whatever it it that we're developing are
public facing, it's desirable to put a facade on our oversights (i.e. a
nice "oops, we made a boo boo" page), and so I think it would make sense to
have a generic server error response. I understand this is WIP, which is
great.

For the time being, is using :responses something which can be used in
the interim, and simply walking the tree that is my bidi routes, and
inserting my default error handler for all resources which don't already
have one defined?

Thanks a lot for a great library.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#55 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAJ9Owy-vTJ9JLbmHuDnurStqRGnitwxks5qhdv4gaJpZM4HTklr
.

from yada.

naartjie avatar naartjie commented on September 27, 2024

Thanks @malcolmsparks.

I have 2 specific use cases, one is being able to define a generic 5xx error page for all routes, or a certain sub-set. And as described above, it would be useful to be able to toggle the stack trace off and on given either prod, or a non-prod setup.

The second one: we are trying to capture and send all 5xx errors to Bugsnag. I am not sure if this is currently possible, but is there an interceptor chain equivalent on the response? How would one go about defining a generic error handler, which would then forward all exceptions, as well as the ctx to bugsnag.

Come to think of it, use case 1 and 2 could possibly be addressed using the same strategy?

from yada.

stijnopheide avatar stijnopheide commented on September 27, 2024

I've built quite a few APIs with yada and the error handling is always a bit odd. Let me describe a bit in detail first the use case and then what I think the problem is.

Use case

Usually the API resources will call some function in a business 'layer'. Errors can be thrown here and do not necessarily know about http status codes. Take as an example e.g. a Datomic Cloud system that throws ExceptionInfo with Cognitect Anomalies error categories, but this will be true for any business logic / database system.

If you do not catch these errors in your :properties or :response methods, they will get translated into internal server errors. Fine so far.

Now, if you do want to turn these errors into something that the HTTP client might react upon, you need some translation mechanism and generate proper status codes. The purpose is to have standardized errors sent to the HTTP client, with a body that can be read programmatically.

There are a couple of options for this in yada right now:

  1. catch exceptions everywhere they can occur (properties, authorization, methods, ...) and translate them into a proper HTTP status. This will have error handling code all over the place and all you want to do is have a ::anomalies/forbidden generate a 403.
  2. use the :responses mechanism to translate the error right before sending it back to the client. This will however still treat the error as an Internal Server Error in yada (i.e. print logs)
  3. walk the bidi tree and update the necessary functions (probably :properties and :response of each method) to wrap with the error handler.

Problems

1. Generic error handler

There is no mechanism for passing an error handler to a resource. Currently there is a default error handler defined in yada.handler. This is however not an error handler, but a logger. Would it be an option to have an error handler either translate the error into a valid next context or throw an error? A bit the same as an error-handler works on core.async channels.
One question that I'm still struggling with is, does this even make sense? E.g. an error occurring during authentication might still have a completely different format/meaning than an error happening during the method call. Other thoughts appreciated.

2. Error interceptor chain does not receive updated context

In case of an error, the error interceptor chain does not receive the ctx as it has been updated so far. This is due to catching only the original context. This removes e.g. an authenticated user from the context, which might be useful information for logging etc.
Not sure how to capture the updated context here, but it needs to interleave the normal interceptor chain with the catch blocks or something.

3. Yada error format specification

When yada generates an error (e.g. for validating query parameters) it generates something of the form of {:errors [["query" {:error {:object "missing-required-key"}}]]}. Is this format described somewhere? If we want to have error bodies read programmatically, it needs to be the same format for yada errors as other 'functional' errors. It's possible to translate a yada error into the agreed format for clients, but how do we detect it is a yada generated error?

from yada.

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.