From 277ae423cbee29af8ae4d5966fbe67d47327a2a3 Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Wed, 26 Oct 2022 17:55:19 -0400 Subject: [PATCH] Caching for categories in the case of network errors --- web/src/api.rs | 28 +++++++++++++++++++++++----- web/src/js_lib.rs | 8 ++++++-- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/web/src/api.rs b/web/src/api.rs index 9db72e4..49dc535 100644 --- a/web/src/api.rs +++ b/web/src/api.rs @@ -14,11 +14,13 @@ use std::collections::BTreeMap; use reqwasm; -use serde_json::{from_str, to_string}; +use serde_json::to_string; use sycamore::prelude::*; use tracing::{debug, error, info, instrument, warn}; use recipes::{parse, Recipe, RecipeEntry}; +use wasm_bindgen::JsValue; +use web_sys::ResponseType; use crate::{app_state, js_lib}; @@ -100,6 +102,12 @@ impl From for String { } } +impl From for Error { + fn from(item: JsValue) -> Self { + Error(format!("{:?}", item)) + } +} + impl From for Error { fn from(item: String) -> Self { Error(item) @@ -136,20 +144,28 @@ impl HttpStore { use_context::>(cx).clone() } - #[instrument] + //#[instrument] pub async fn get_categories(&self) -> Result, Error> { let mut path = self.root.clone(); path.push_str("/categories"); let resp = reqwasm::http::Request::get(&path).send().await?; + let storage = js_lib::get_storage(); if resp.status() == 404 { debug!("Categories returned 404"); + storage.remove_item("categories")?; Ok(None) } else if resp.status() != 200 { - Err(format!("Status: {}", resp.status()).into()) + if resp.type_() == ResponseType::Error { + let categories = storage.get("categories")?; + Ok(categories) + } else { + Err(format!("Status: {}", resp.status()).into()) + } } else { debug!("We got a valid response back!"); - let resp = resp.json().await; - Ok(Some(resp.map_err(|e| format!("{}", e))?)) + let resp: String = resp.json().await?; + storage.set("categories", &resp)?; + Ok(Some(resp)) } } @@ -203,6 +219,8 @@ impl HttpStore { pub async fn save_categories(&self, categories: String) -> Result<(), Error> { let mut path = self.root.clone(); path.push_str("/categories"); + let storage = js_lib::get_storage(); + storage.set("categories", &categories)?; let resp = reqwasm::http::Request::post(&path) .body(to_string(&categories).expect("Unable to encode categories as json")) .header("content-type", "application/json") diff --git a/web/src/js_lib.rs b/web/src/js_lib.rs index 2cb040b..0ab757b 100644 --- a/web/src/js_lib.rs +++ b/web/src/js_lib.rs @@ -29,6 +29,10 @@ where } } -pub fn get_storage() -> Result, JsValue> { - window().expect("No Window Present").local_storage() +pub fn get_storage() -> Storage { + window() + .expect("No Window Present") + .local_storage() + .expect("Failed to get storage") + .expect("No storage available") }