Phoenix Error Rendering & Multiple Endpoints

These are both likely a case of either “holding the tool wrong” or “using the wrong tool”, but I am looking for information and advice.

We have built our Phoenix app in such a way that we have, excepting for ErrorView, never used a view (we are an API-only setup, and use GraphQL as our primary API, but have integrations and other needs where we have some non-GraphQL (mostly JSON) APIs. There are very few “resources”. Our controller methods (often not called by the traditional names because they aren’t resources) mostly use Phoenix.Controller.json/2 directly for rendering.

Question 1

Is there a way to handle errors directly in a Phoenix application without defining render_errors[view: …] (up to 1.6) or render_errors[formats: …] (1.7+)?

Question 2

I believe that we have been also doing things wrong with how we handle certain sub-applications (we use an umbrella).

Our app structure looks something like this:

  • MyApp
  • clients:
    • MyApp.Client1
    • MyApp.Client2
  • MyApp.GraphQL
  • MyApp.Web

MyApp.Web has defined an endpoint, and it defines forward routes (excessively simplified here):

forward "/graphql", MyApp.GraphQL
forward "/clients/one", MyApp.Client1.Router
forward "/clients/two", MyApp.Client2.Router
# ...

As of right now, each client (MyApp.Client1, MyApp.Client2, etc.) defines another Phoenix.Endpoint for testing (but not for non-test mode). Is there a good reason to define such an Endpoint, or is there a way to avoid defining such an Endpoint as it is not used in the normal implementation?

We can’t reference MyApp.Web.Endpoint from MyApp.Client1 (etc.) without getting a cross-reference issue (access is always up in the list; client apps have no knowledge of one another, etc.).

What’s the reason for trying to avoid them? You’ll always have errors that you cannot handle explicitly. E.g. a 500 is almost by definition an error you didn’t handle. Your remarks make it sound like views are something to be avoided, which isn’t the case.

You could use a test endpoint, where you forward requests at runtime to different routers based on some information in the conn, which you setup in tests.

1 Like