DataSource rename to BackendTasks, and Exception Handling #355
Replies: 2 comments 4 replies
-
|
The idea of passing off the handling of an exception to the runtime sounds really nice! It immediately reminded me of my recent use of As far as naming, I definitely like the move away from I do wonder, and may try to see, if I can use elm-pages as a cli for running my toy language instead of elm-posix. The idea of it possibly caching sounds intriguing for a cli tool, especially since I want to load data from both the file system and uris. Also sounds nice as I've been doing Advent of Code and I'm always nervous to do what some people do and hit the website directly to get the input instead of manually copy/pasting it. |
Beta Was this translation helpful? Give feedback.
-
|
Just a thought about the name BackendTask: wouldn't it be better named BuildTask? Backend is something I usually associate with a server running after build/deployment. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Background
With the new features in the elm-pages v3 beta, I've taken a step back to think about the core abstraction of elm-pages. For example, with server-rendered routes, and
actions, DataSource's have expanded to do more than just pulling in static data. Now it is used for:elm-pages runcommandThis means it is likely you will want to do more sophisticated things like recovering from HTTP errors (if an HTTP API request fails with validations, for example). And the abstraction isn't only about pulling in data - when the only goal is to fire and forget an effectful API request, the term DataSource doesn't fit so well.
Changes: Rename to BackendTask and Exceptions
To better reflect this, I'm making 3 changes around DataSources:
DataSource->BackendTaskDataSource value->BackendTask error valueBackendTaskcan cause an error or not by its error type variable - for example,BackendTask.succeed "Hello"gives youBackendTask error String. You don't need to usethrowwhen there are no possible errors like inBackendTask.succeedHere's what that looks like in practice. A few things to notice in this example:
Exceptiontype is useful for taking aBackendTask's error values in one of two paths: throwing to ignore the error and pass it up to the framework if something goes wrong, or catch to unwrap the nicely typed error data so you can handle itBackendTask.throw : BackendTask (Catchable error) data -> BackendTask Throwable data- this is in contrast toBackendTask.catch : BackendTask (Catchable error) value -> BackendTask error valueBackendTask.File,BackendTask.Glob,BackendTask.Httphave nicely typed error data and return their own error types wrapped withCatchable. But users can createCatchable errortypes to enable this same flow, or they can directly create aThrowablewhich can lets the framework handle the unexpected errorhttps://github.com/dillonkearns/elm-pages-v3-beta/blob/backend-tasks/examples/docs/app/Route/Docs/Section__.elm#L133-L164
elm-pages Exceptions compared to traditional exception handling
I'm not a fan of exceptions in other languages because of the way they introduce a new control flow mechanism, and because you can't tell which code could have a possible exception lurking, or whether the code above it is handling exceptions or not. There is also a strange back-and-forth where you could throw and catch exceptions at different levels and pass an error multiple directions.
With this abstraction, I think of this as "Managed Exceptions", just as many languages have side-effects while Elm has "Managed Effects." Similar to Managed Effects in Elm, Exceptions in elm-pages don't do anything in themselves, rather they need to be passed to the framework. Elm Managed Effects need to be passed to
initorupdate, and elm-pages Exceptions need to be the final result of theerrortype variable inBackendTask Throwable value(whereThrowableis just an alias toException ()).The goal here is to give you explicitness of errors that come in vanilla Elm
Tasks, but whereas regular Task's give you aMsgwith aResultin it that you always need to explicitly handle,elm-pagesBackendTasks give you a way to not handle certain error cases yourself but pass them to the framework to give an error status in the CLI or a server error code response for errors that you don't want to explicitly handle. So you have all the explicitness of error handling that we're familiar with in Elm and Task's, but the added convenience that we can let the framework give us nice error messages for cases that we don't expect and don't want to catch.Performing all BackendTask's
Previously, DataSource's would cache all previous results in the chain of DataSource running, so if you hit an API it would never make that exact same API request twice but instead would just use the previous result.
This abstraction doesn't work for new effectful uses, such as
elm-pages runscripts, or hitting effectful APIs from anaction, where you want to be sure those effects are performed each time they're called.It may take some iteration to figure out a nice way to allow for caching when the user wants it, for example to only make a given API request once and cache it any other time it's hit.
Feedback
I'd love to hear from you if you have thoughts on these APIs. Thanks for reading!
Beta Was this translation helpful? Give feedback.
All reactions