#[non_exhaustive]pub enum WriteError<K = String> {
Refused(FieldErrors<K>),
Declined(Text),
Failed(Error),
}Expand description
Why a record fn or an action’s run wrote nothing: a refusal the page shows, or a failure.
Either way the handler rolls the transaction back, so whatever the fn wrote before it returned is undone.
Refusedrenders the form again with status 200, each error under the control of the field it names, as avalidate_recorderror does. A record fn keys its errors by the record form’s field enum, an action’s run by its input’s, so a renamed field fails to compile rather than render no message.Declinedrefuses with a message that belongs to no field: a paid invoice that cannot be deleted. A record form renders again with the message above its fields; a delete, a restore or an action flashes it and lands back where it started.Failedanswers as a failed write does: a record fn’s collision on a unique index renders under the field’s control, a save another save overtook renders the stale form, and any other error flashes the failure toast and answers with the error.
A refusal is the answer to a rule that reads the database: a stock level, a quota, a uniqueness no index models. A rule the write itself enforces holds against concurrent writes: an update filtered on the stock it needs that matches no row refuses the very write it would have made.
? turns any error a topcoat::Error takes into Failed, and a
FieldErrors into Refused:
use tablo_core::{FieldErrors, RecordForm, Resource, WriteError, write_create};
use topcoat::context::Cx;
impl Resource for OrderResource {
type Model = Order;
type Form = OrderForm;
async fn create_record(
cx: &Cx,
form: OrderForm,
ex: &mut dyn toasty::Executor,
) -> Result<Order, WriteError<OrderFormField>> {
let stock = Stock::filter_by_sku(&form.sku)
.first()
.exec(&mut *ex)
.await?;
if stock.is_none_or(|stock| stock.level < form.quantity) {
let mut errors = FieldErrors::new();
errors.add(OrderFormField::Quantity, "Not enough in stock");
return Err(errors.into());
}
write_create::<Self>(cx, form, ex).await
}
}Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Refused(FieldErrors<K>)
The submission cannot stand: render the form again with these errors.
Declined(Text)
The write cannot stand, for a reason that names no field: show this message.
Failed(Error)
The write failed: answer with this error and the failure toast.