Comments (12)
Accepted
from yada.
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.
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.
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.
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.
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.
Ah, in that case this is an issue - let's keep it open
from yada.
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.
Today I was googling for yada exception handling and I clicked through on one of the links:
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.
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.pngOnce 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.
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.
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:
- 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. - 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) - 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)
- Authentication schemes cannot be configured per request method HOT 3
- Request Body not present in ctx in case plumatic schema validation failure, defined in resource. HOT 2
- Yada manual edge example out of date HOT 3
- More reflection warnings HOT 1
- Incorrect multipart header processing
- Unable to access content-type in authorization
- Multipart throws "Malformed boundary" error when sent an empty submission
- is CI broken? HOT 1
- yada.swagger-parameters & yada.parameters are almost the same code. HOT 1
- :x-frame-options DENY is not a valid value
- Assumes clj-time will come in through ring-core (aka incompatible with ring-core 1.8.1)
- Plans for PATCH support
- Impossible to pretty-print response bodies by using `pretty=true` media type parameter
- Is it possible to determine if a path/href string is part of my system? HOT 1
- Yada may give out of memory exception (java.lang.OutOfMemoryError, OOM) when put under load
- Unsetting cookies: expires vs max-age
- `content-length` is incorrectly set to 0 when responding with HTTP 304 to GET requests
- Cannot use aleph 0.5.0 with yada HOT 6
- Test failure on master
- 404 for docs link
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from yada.