use super::*;
pub trait Core: Debug {
- #[throws(OnlineError)]
+ #[throws(Fatal)]
fn check_held(&self, pc: &GPiece, player: PlayerId) {
if pc.held != None && pc.held != Some(player) {
- throw!(OnlineError::PieceHeld)
+ throw!(Fatal::PieceHeld)
}
}
}
#[derive(Error,Debug)]
#[error("{0}")]
-pub struct OnlineErrorResponse(#[from] OnlineError);
+pub struct FatalErrorResponse(#[from] Fatal);
-impl From<&OnlineErrorResponse> for rocket::http::Status {
- fn from(oe: &OnlineErrorResponse) -> rocket::http::Status {
- use OnlineError::*;
+impl From<&FatalErrorResponse> for rocket::http::Status {
+ fn from(oe: &FatalErrorResponse) -> rocket::http::Status {
+ use Fatal::*;
match oe.0 {
ServerFailure(_) => Status::InternalServerError,
NoClient | NoPlayer(_) | GameBeingDestroyed(_)
}
}
-impl<'r> Responder<'r> for OnlineErrorResponse {
+impl<'r> Responder<'r> for FatalErrorResponse {
#[throws(Status)]
fn respond_to(self, req: &Request) -> Response<'r> {
let msg = format!("Online-layer error\n{:?}\n{}\n", self, self);
let piece = vpiece_decode(gs, player, gpl, form.piece);
if_let!{ Some(piece) = piece; else return Ok(()) }
let was_held = gs.pieces.get(piece).as_ref().map(|gpc| gpc.held);
- use ApiPieceOpError::*;
match (||{
let ipc = ipieces.get(piece).ok_or(POE::PieceGone)?;
debug!("client={:?} pc.lastclient={:?} pc.gen_before={:?} pc.gen={:?} q_gen={:?} u_gen={:?}", &client, &gpc.lastclient, &gpc.gen_before_lastclient, &gpc.gen, &q_gen, &u_gen);
- if u_gen > q_gen { throw!(PieceOpError::Conflict) }
+ if u_gen > q_gen { throw!(Inapplicable::Conflict) }
trace_dbg!("form.op", player, piece, &form.op, &gpc);
form.op.check_held(gpc,player)?;
let update =
})?;
Ok::<_,ApiPieceOpError>(update)
})() {
- Err(ReportViaUpdate(poe)) => {
+ Err(APOE::Inapplicable(poe)) => {
PrepareUpdatesBuffer::piece_report_error(
&mut ig, poe,
piece, vec![], POEPP::Unprocessed, client, form.cseq,
)?;
debug!("api_piece_op Err(RVU): {:?}", &form);
},
- Err(PartiallyProcessed(poe, logents)) => {
+ Err(APOE::PartiallyProcessed(poe, logents)) => {
PrepareUpdatesBuffer::piece_report_error(
&mut ig, poe,
piece, logents, POEPP::Partially, client, form.cseq,
)?;
debug!("api_piece_op Err(PP): {:?}", &form);
},
- Err(ReportViaResponse(err)) => {
+ Err(APOE::Fatal(err)) => {
warn!("api_piece_op ERROR {:?}: {:?}", &form, &err);
Err(err)?;
},
"grasped"
)?;
- if gpc.held.is_some() { throw!(OnlineError::PieceHeld) }
+ if gpc.held.is_some() { throw!(Fatal::PieceHeld) }
gpc.held = Some(player);
let update = PieceUpdateOp::ModifyQuiet(());
}
impl op::Core as {
- #[throws(OnlineError)]
+ #[throws(Fatal)]
fn check_held(&self, _pc: &GPiece, _player: PlayerId) { }
}
then {
let z = gs.max_z.z.clone_mut().increment().map_err(
- |e| APOE::ReportViaResponse(IE::from(e).into()))?;
+ |e| APOE::Fatal(IE::from(e).into()))?;
Some(ZLevel { z, zg: gs.gen })
}
else { None }
)?;
let who_by = who_by.ok_or(POE::PieceGone)?;
- if gpc.held != Some(player) { throw!(OnlineError::PieceHeld) }
+ if gpc.held != Some(player) { throw!(Fatal::PieceHeld) }
gpc.held = None;
let wrc = if let Some(zlevel) = new_z {
to_recalculate,
piece,
vanilla,
- ).map_err(|e| OnlineError::from(e))?;
+ ).map_err(|e| Fatal::from(e))?;
update
}
struct ApiPieceMove(Pos);
impl op::Core as {
- #[throws(OnlineError)]
+ #[throws(Fatal)]
fn check_held(&self, gpc: &GPiece, player: PlayerId) {
// This will ensure that occultations are (in general) properly
// updated, because the player will (have to) release the thing
// again
- if gpc.held != Some(player) { throw!(OnlineError::PieceHeld) }
+ if gpc.held != Some(player) { throw!(Fatal::PieceHeld) }
if gpc.occult.is_active() { throw!(OE::Occultation) }
if matches_doesnot!(
gpc.moveable(),
Err(pote) => {
gpc.pos = pote.clamped;
throw!(ApiPieceOpError::PartiallyProcessed(
- PieceOpError::PosOffTable,
+ Inapplicable::PosOffTable,
logents,
));
}
pub use rocket_contrib::templates::Template;
pub use crate::api::InstanceAccess;
-pub use crate::api::{OnlineErrorResponse};
+pub use crate::api::{FatalErrorResponse};
pub use crate::cmdlistener::*;
-pub type OER = OnlineErrorResponse;
+pub type OER = FatalErrorResponse; // xxx rename this alias
use rocket::fairing;
use rocket::response::Content;
use crate::prelude::*;
#[derive(Error,Debug)]
-pub enum OnlineError {
+pub enum Fatal { // Includes _bogus_ client updates, see PROTOCOL.md
#[error("Game in process of being destroyed")]
GameBeingDestroyed(#[from] GameBeingDestroyed),
#[error("client session not recognised (terminated by server?)")]
#[error("JSON deserialisation error: {0}")]
BadJSON(serde_json::Error),
#[error("referenced piece is gone (maybe race)")]
- PieceHeld,
+ PieceHeld, // xxx should be _inapplicable_
#[error("improper UI operation")]
- PieceImmoveable,
+ PieceImmoveable, // xxx should be _inapplicable_
#[error("improper UI operation")]
- BadOperation,
+ BadOperation, // xxx should be _inapplicable_
#[error("overlapping occultation")]
- OverlappingOccultation,
+ OverlappingOccultation, // xxx should be _inapplicable_
#[error("piece is occulting, or occulted")]
- Occultation,
+ Occultation, // xxx should be _inapplicable_
#[error("UI operation not valid in the curret piece state")]
- BadPieceStateForOperation,
+ BadPieceStateForOperation, // xxx should be _inapplicable_
}
#[derive(Error,Debug)]
#[derive(Error,Debug)]
pub enum ApiPieceOpError {
- ReportViaResponse(#[from] OnlineError),
- ReportViaUpdate(#[from] PieceOpError),
+ Fatal(#[from] Fatal),
+ Inapplicable(#[from] Inapplicable),
/// This error is always generated in the context of a piece
/// operation by a particular client. It corresponds roughly to a
/// PieceUpdateFromOp for other clients of (Unpredicable,
/// PieceUpdateOp::Modify, ..).
/// For this client it is that but also an error report.
- PartiallyProcessed(PieceOpError, Vec<LogEntry>),
+ PartiallyProcessed(Inapplicable, Vec<LogEntry>),
}
display_as_debug!(ApiPieceOpError);
impl From<PlayerNotFound> for ApiPieceOpError {
fn from(x: PlayerNotFound) -> ApiPieceOpError {
- ApiPieceOpError::ReportViaResponse(x.into())
+ ApiPieceOpError::Fatal(x.into())
}
}
impl From<InternalError> for ApiPieceOpError {
fn from(x: InternalError) -> ApiPieceOpError {
- ApiPieceOpError::ReportViaResponse(x.into())
+ ApiPieceOpError::Fatal(x.into())
}
}
PlayerRemoved, // appears only in streams for applicable player
TokenRevoked, // appears only in streams for applicable player
PieceOpError {
- error: PieceOpError,
+ error: Inapplicable,
partially: PieceOpErrorPartiallyProcessed,
state: POEPU,
},
display_as_debug!{PieceOpErrorPartiallyProcessed}
#[derive(Error,Debug,Serialize,Copy,Clone)]
-pub enum PieceOpError {
+pub enum Inapplicable {
Conflict,
PosOffTable,
PieceGone,
OcculterAlreadyRotated,
OrganisedPlacementOverfull,
}
-display_as_debug!{PieceOpError}
+display_as_debug!{Inapplicable}
pub type StartupError = anyhow::Error;
-pub use OnlineError::{NoClient,NoPlayer};
+pub use Fatal::{NoClient,NoPlayer};
pub enum AggregatedIE {
Ok,
pub type TokenTable<Id> = HashMap<RawToken, InstanceAccessDetails<Id>>;
pub trait AccessId: Copy + Clone + 'static {
- type Error: Into<OnlineError>;
+ type Error: Into<Fatal>;
const ERROR: Self::Error;
fn global_tokens(_:PrivateCaller) -> &'static RwLock<TokenTable<Self>>;
fn tokens_registry(ig: &mut Instance, _:PrivateCaller)
}
}
impl AccessId for ClientId {
- type Error = OnlineError;
- const ERROR: OnlineError = NoClient;
+ type Error = Fatal;
+ const ERROR: Fatal = NoClient;
fn global_tokens(_: PrivateCaller) -> &'static RwLock<TokenTable<Self>> {
&GLOBAL.clients
}
impl ById for GPieces {
type Id = PieceId;
type Entry = GPiece;
- type Error = PieceOpError;
+ type Error = Inapplicable;
#[throws(POE)]
fn byid(&self, piece: PieceId) -> &GPiece {
self.get(piece).ok_or(POE::PieceGone)?
}
pub fn occulter_check_unrotated(&self, _:ShowUnocculted)
- -> Result<OcculterRotationChecked, PieceOpError> {
+ -> Result<OcculterRotationChecked, Inapplicable> {
if self.angle.is_rotated() { Err(POE::OcculterAlreadyRotated) }
else { Ok(OcculterRotationChecked(())) }
}
} }
}
-#[throws(OnlineError)]
+#[throws(Fatal)]
pub fn create_occultation(
gen: &mut UniqueGenGen,
max_z: &mut ZLevel,
type ZLevels = IndexVec<InHand, ZLevel>;
type OrderTable = IndexVec<InHand, InHand>;
-#[throws(PieceOpError)]
+#[throws(Inapplicable)]
fn recover_order(region: &Rect, pieces: &Primary, zlevels: &ZLevels)
-> OrderTable
{
for &pos in &layout {
// Some sanity checks
pos.clamped(gs.table_size).map_err(
- |_| APOE::ReportViaUpdate(POE::PosOffTable))?;
+ |_| APOE::Inapplicable(POE::PosOffTable))?;
match gs.occults.pos_occulter(&gs.occults, pos)? {
None => {},
Some(occulter) if occulter == apiece => {},
- Some(_) => throw!(APOE::ReportViaUpdate(POE::Occultation)),
+ Some(_) => throw!(APOE::Inapplicable(POE::Occultation)),
};
}
pub type APOE = ApiPieceOpError;
pub type ESVU<POEPU> = ErrorSignaledViaUpdate<POEPU>;
pub type IE = InternalError;
-pub type OE = OnlineError;
-pub type POE = PieceOpError;
+pub type OE = Fatal; // xxx get rid of this alyas when we've cleaned up Fatal
+pub type POE = Inapplicable; // xxx rename this alias
pub type POEPP = PieceOpErrorPartiallyProcessed;
pub type SvgE = SVGProcessingError;
pub type SpE = SpecError;
}
pub fn piece_report_error(ig: &mut Instance,
- error: PieceOpError, piece: PieceId,
+ error: Inapplicable, piece: PieceId,
logents: Vec<LogEntry>,
partially: PieceOpErrorPartiallyProcessed,
client: ClientId, cseq: ClientSequence)