-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
External secondary instances: Error conditions #202
Comments
Some possible considerations:
|
In our discussion yesterday, we generally decided to go with Option 1. We didn't get too deep into details about what the There's a good possibility Options 1 and 2 may blur in that process. As mentioned in this comment:
|
Where a “form load failure” is any Promise rejection produced by the engine’s `initializeForm` entrypoint. This is intentionally broad, and what I think is a relatively minimal first pass that might be useful to users (and to us). “Relatively” minimal because I took the opportunity to lay a bit of groundwork for a few things either cued for near term work, or ripe for near term improvement. Notable among those: - Establish a more intentional approach to use of test fixtures in the `web-forms` package. This includes a dedicated fixtures directory (alongside those already used by `scenario`), and a narrower “test helper” (ugh) to access those. That access point also includes some additional breadcrumbs for ways we might improve fixture access in the future. - `FormLoadFailure` begins laying a bit of groundwork for the incoming, much more comprehensive overhaul of error messaging. - Actually tests a few different form load failure conditions. I believe these will be useful for catching potential regressions in that overhaul, as well in other future work around those specific failure modes. UI/UX/presentation design note: I had a brief discussion with @alyblenkin about this being a minimal first step. We agreed that this seems like a reasonable first pass, and agreed there’s more to do in near-future iterations. Things which are currently lacking from a UX perspective, blocked by work with a larger scope: - Better messaging of specific errors. We’ll be cataloguing known cases as part of #202, which will give us a much clearer picture of how to address this. - Any kind of direct prompt for user action. Deferred for the same reasons. - Ability to close the dialog or go back. Deferred because this would expand scope to navigation more generally, which we should look at more holistically.
Where a “form load failure” is any Promise rejection produced by the engine’s `initializeForm` entrypoint. This is intentionally broad, and what I think is a relatively minimal first pass that might be useful to users (and to us). “Relatively” minimal because I took the opportunity to lay a bit of groundwork for a few things either cued for near term work, or ripe for near term improvement. Notable among those: - Establish a more intentional approach to use of test fixtures in the `web-forms` package. This includes a dedicated fixtures directory (alongside those already used by `scenario`), and a narrower “test helper” (ugh) to access those. That access point also includes some additional breadcrumbs for ways we might improve fixture access in the future. - `FormLoadFailure` begins laying a bit of groundwork for the incoming, much more comprehensive overhaul of error messaging. - Actually tests a few different form load failure conditions. I believe these will be useful for catching potential regressions in that overhaul, as well in other future work around those specific failure modes. UI/UX/presentation design note: I had a brief discussion with @alyblenkin about this being a minimal first step. We agreed that this seems like a reasonable first pass, and agreed there’s more to do in near-future iterations. Things which are currently lacking from a UX perspective, blocked by work with a larger scope: - Better messaging of specific errors. We’ll be cataloguing known cases as part of #202, which will give us a much clearer picture of how to address this. - Any kind of direct prompt for user action. Deferred for the same reasons. - Ability to close the dialog or go back. Deferred because this would expand scope to navigation more generally, which we should look at more holistically.
- For now, we’ll go with the name suggested in review. As discussed there, we have broader goals for error reporting, but we can address those in a non-bandaid change (i.e. supporting #202) - Aligns the module and class name
This design issue is part of broader support for external secondary instances:
jr:
URLsThis issue is focused on:
Anticipated error conditions
The error conditions I expect we'll need to handle fall into three buckets:
I don't intend to detail all of the specific cases yet, but I think we should be prepared to define a specific set of expected error conditions as a prerequisite for implementation. This way we can plan and design accordingly for the various downstream user flow and/or messaging suitable for each case.
Worth mentioning on that note: depending on how we prioritize functionality, we may want to take special care to distinguish between unsupported data types we know about, and plan to support versus those we simply don't recognize.
Deeper consideration of "error" as a binary state
There's probably room for nuance in both buckets. We might want to also consider some partial and recoverable failure cases:
I would categorize these as future considerations, out of scope for now unless there's a compelling reason to prioritize otherwise.
But I mention them both because it's good to anticipate future goals, and because they're important to keep in mind as we consider the implications of the next section.
Goal: represent error conditions on par with success conditions
This is something I wish I had made more explicit when I wrote up #188, to avoid confusion on why some of the proposal is shaped the way it is. To be very clear:
Documentation-first: an ongoing goal of designs for
@getodk/xforms-engine
is to make documentation a core work product, in a way that is and remains consistent with the documented functionality.Documentation of failure modes (and other non-happy path cases): a long-discussed goal—now coming into focus as we take on functionality with inherent fallibility—is to ensure that failure modes and error conditions are documented in a way that's consistent with success modes.
There are some fundamental limitations we face here, either imposed by the platform or our development stack (or both). In particular, since we rely heavily on the TypeScript type system to deliver documentation, we must accept that exceptions—and especially the
throw
keyword—are antithetical to these goals.Options
Option 0:
throw
anywayMaybe we decide that the explicit goals described above are misaligned, or that we have some other way of accommodating those goals besides avoiding
throw
as an error conveyance mechanism.If we do this, I would want to have strong assurances that we can provide comparable documentation experience:
@getodk/xforms-engine
Option 1:
Result
typeFortunately, there's a wealth of prior art we can draw from! A
Result
type is an obvious candiate to represent the result of explicitly fallible operations. It has very clear practical benefits for our usage:One drawback is that a
Result
type specifically is not necessarily the best representation of an operation which may be partially successful, recoverable, etc. We should be prepared to adapt this approach as appropriate to any of the more ambiguous conditions described above and/or any others we may think of while we prepare for this functionality.Option 2: some other non-
Result
value representationIt's possible we decide that a
Result
type specifically is not up to the task, perhaps because of the nuances of error conditions we expect to handle. This option could be either:The latter could have some overlap with other changes we expect to introduce in the engine representation.
What about everything we already
throw
?If we decide to go with either option 1 or option 2, there's a nagging problem: we already have quite a lot of
throw
statements throughout the codebase. Many of which are haphazard, without much if any discernable systematic consideration. Quite a few don't even throw instances ofError
! 😰I don't think this should preclude us from adopting either option. And I don't think it requires us to deal with all of this baggage upfront either. Choosing either option now, with some forethought, can give us a clear framework for improving on this extant problem, and the flexibility to do it as aggressively (or not) as we like.
Especially if we choose option 1, a project I've recently had my eye on would almost certainly be helpful:
neverthrow
. Aside from providing clearResult
-specific patterns with convenient (even approaching idiomatic!) APIs, I also understand it to be pretty pragmatic in how it addresses the awkward "some errors known" situation we'll be in.The text was updated successfully, but these errors were encountered: