Returning Errors and not throwing

I am messing around with actions and useSubmission and I have seen Ryan and the docs mention it is best to return, not throw, Errors
Rather than throwing errors, it is recommended to return them from actions. This helps with the typing of submissions that would be used with useSubmission. This is important when handling progressive enhancement where no JavaScript is present in the client, so that errors can be used declaratively to render the updated page on the server.
Rather than throwing errors, it is recommended to return them from actions. This helps with the typing of submissions that would be used with useSubmission. This is important when handling progressive enhancement where no JavaScript is present in the client, so that errors can be used declaratively to render the updated page on the server.
I dont understand the "so that errors can be used declaratively to render the updated page on the server" part Isnt the use of actions in forms and useSubmission always on the client? How are we rendering and updated page on the server? Dont we look at the submission and change the page on the client accordingly? (granted this requires JS)
6 Replies
peerreynders
peerreynders7mo ago
“No Javascript on the client” for a PE app means that every navigation, etc. requires a page load/round trip to the server so that everything is rendered on the server every time. There is no rendering on the client. So in a PE app when an Error is part of the normal rendering flow on the server it's better to handle the Error via normal control flow rather than engaging the stack unwinding of the exception system. Perhaps the lesser issue is that exception handling does impose some overhead on the server.
agustafson
A List Apart
Understanding Progressive Enhancement
Steven Champeon turned web development upside down, and created an instant best practice of standards-based design, when he introduced the notion of designing for content and experience instead of …
Stack Overflow
NodeJS: Is there still a performance penalty to throwing Errors?
Depending on the nodejs framework, there are usually two ways to manage errors. Throw them (ie throw new Error('invalid id');) Return them (ie return { 400: 'invalid id' };) Due to old advice that
sabercoy
sabercoyOP7mo ago
I understand PE, and I understand the stated desire to handle Errors with normal control flow I do not understand how this gets incorporated, in code, with SolidStart's primitives (action and useSubmission) My understanding is that a server-action is called from a form that is on the client. Now we are in the server handling the action, and now we run into an Error. Even if I choose to return this error and not throw it, how is it that I can "declaratively render the updated page on the server"? My understanding is that an action can just revalidate or redirect or reload, it doesnt arbitrarily change something in the DOM on the page? If I were to revalidate, redirect, or reload, then what does it matter if I return the Error? Isnt the important part the fact that I either revalidated, redirected, or reloaded? Is there any example of what the docs are talking about? Something that returns Errors and uses useSubmission and "render the updated page on the server"
peerreynders
peerreynders7mo ago
Is there any example
https://github.com/solidjs/solid-start/blob/74ceb8076d12916526e305581ddb8416779be504/examples/with-auth/src/lib/index.ts#L27-L47 Install the example and turn off javascript in the browser and watch the network tab. - On login success the server responds with a redirect status and a location header to / or whatever redirectTo search param referred to. - On login failure the server response contains the /login page: freshly rendered this time including information provided by the returned error.
https://github.com/solidjs/solid-start/blob/74ceb8076d12916526e305581ddb8416779be504/examples/with-auth/src/routes/login.tsx#L34-L38
GitHub
solid-start/examples/with-auth/src/lib/index.ts at 74ceb8076d129165...
SolidStart, the Solid app framework. Contribute to solidjs/solid-start development by creating an account on GitHub.
GitHub
solid-start/examples/with-auth/src/routes/login.tsx at 74ceb8076d12...
SolidStart, the Solid app framework. Contribute to solidjs/solid-start development by creating an account on GitHub.
sabercoy
sabercoyOP7mo ago
thanks for this example, in looking at this I have discovered the key is that the behavior under the hood of SS is different depending on JS being enabled if enabled, it sends a fetch request, and in the response it has the information needed to dynamically update the UI in the spot of the read submission (in 1 request) if disabled, it sends a request, and in the response is instructed to refetch the same page which will have the UI updated in the spot of the read submission (it takes 2 requests) that covers the useSubmission and render the updated page on the server, but now there is returning the Error vs throwing. I see this decision as ultimately deciding to use submission.result or submission.error. The only reason I can see to return the Error is you will get the type information in the result, where as if you throw, the error would still just be any
peerreynders
peerreynders7mo ago
The only reason I can see to return the Error
… until you start looking at the client side JS case again. IIRC a submission that returns undefined clears itself. So the happy path with the redirect doesn't leave a submission in the pool, while the Error result is essential but needs submission.clear(). Now that doesn't really stop you from using submission.error instead of submission.result as both can be cleared. The consideration that probably tips the balance is that a failed registration/login should be considered an “expected error” which is a type of “result” rather than a truly “exceptional condition” which describes a “non-recoverable/have to start from square one” situation.
sabercoy
sabercoyOP7mo ago
hmm I didnt even know submission.clear was a thing I see in the no-JS case it really is not meaningful (the page you got is the result of the submission) but in the JS case the submissions seem to stack on themselves and are popped with clear()
Want results from more Discord servers?
Add your server