From 817b0e76d4b9f5b22e08e90e946af1c14b6cc3e6 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Fri, 21 Jan 2022 16:07:03 -0800 Subject: rust: swith postgresql database to 'fatcat_dev' (distinct from 'fatcat_test') --- rust/HACKING.md | 2 +- rust/README.md | 2 +- rust/example.env | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'rust') diff --git a/rust/HACKING.md b/rust/HACKING.md index fbdeb499..997c849d 100644 --- a/rust/HACKING.md +++ b/rust/HACKING.md @@ -50,7 +50,7 @@ Update Rust database schema (after changing raw SQL schema): Debug SQL schema errors (if diesel commands fail): - psql fatcat_test < migrations/2019-01-01-000000_init/up.sql + psql fatcat_dev < migrations/2019-01-01-000000_init/up.sql ## Direct API Interaction diff --git a/rust/README.md b/rust/README.md index 36061240..e9752fa7 100644 --- a/rust/README.md +++ b/rust/README.md @@ -41,7 +41,7 @@ commands from that user. To create the database account: Copy `./example.env` to `./.env` and update the `DATABASE_URL` and `TEST_DATABASE_URL` lines with the password you set above. -As your regular user, use `diesel` to create and initialize the `fatcat` +As your regular user, use `diesel` to create and initialize the `fatcat_dev` database (`diesel` and the fatcat tools will automatically use postgresql credentials from the `.env` file) as well as the `fatcat_test` database for automated tests: diff --git a/rust/example.env b/rust/example.env index 9b59f28d..4ca8a170 100644 --- a/rust/example.env +++ b/rust/example.env @@ -1,4 +1,4 @@ -DATABASE_URL=postgres://fatcat:tactaf@localhost/fatcat +DATABASE_URL=postgres://fatcat:tactaf@localhost/fatcat_dev TEST_DATABASE_URL=postgres://fatcat:tactaf@localhost/fatcat_test AUTH_LOCATION="dev.fatcat.wiki" AUTH_KEY_IDENT="20190101-dev-dummy-key" -- cgit v1.2.3 From c8b2d48106f92215ca2fbd761f8ac4cf254135e6 Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Fri, 21 Jan 2022 16:42:58 -0800 Subject: rust: handle database read-only mode (as 5xx errors, not 4xx) --- rust/src/endpoints.rs | 14 +++++++------- rust/src/errors.rs | 10 +++++++++- 2 files changed, 16 insertions(+), 8 deletions(-) (limited to 'rust') diff --git a/rust/src/endpoints.rs b/rust/src/endpoints.rs index e04e7315..1a37ecfe 100644 --- a/rust/src/endpoints.rs +++ b/rust/src/endpoints.rs @@ -36,7 +36,7 @@ macro_rules! generic_auth_err_responses { match $val { NotFound(_, _) | DatabaseRowNotFound => $resp_type::NotFound($val.into()), InvalidCredentials(_) | InsufficientPrivileges(_) => $resp_type::Forbidden($val.into()), - DatabaseError(_) | InternalError(_) => { + DatabaseError(_) | InternalError(_) | DatabaseReadOnly => { error!("{}", $val); capture_fail(&$val); $resp_type::GenericError($val.into()) @@ -51,7 +51,7 @@ macro_rules! generic_err_responses { //use crate::errors::FatcatError::*; match $val { NotFound(_, _) | DatabaseRowNotFound => $resp_type::NotFound($val.into()), - DatabaseError(_) | InternalError(_) => { + DatabaseError(_) | InternalError(_) | DatabaseReadOnly => { error!("{}", $val); capture_fail(&$val); $resp_type::GenericError($val.into()) @@ -1100,7 +1100,7 @@ impl Api for Server { NotFound(_, _) | DatabaseRowNotFound => { CreateEditgroupResponse::NotFound(fe.into()) } - DatabaseError(_) | InternalError(_) => { + DatabaseError(_) | InternalError(_) | DatabaseReadOnly => { error!("{}", fe); capture_fail(&fe); CreateEditgroupResponse::GenericError(fe.into()) @@ -1209,7 +1209,7 @@ impl Api for Server { { Ok(changelog) => GetChangelogResponse::Success(changelog), Err(fe) => match fe { - DatabaseError(_) | InternalError(_) => { + DatabaseError(_) | InternalError(_) | DatabaseReadOnly => { error!("{}", fe); capture_fail(&fe); GetChangelogResponse::GenericError(fe.into()) @@ -1274,7 +1274,7 @@ impl Api for Server { InvalidCredentials(_) | InsufficientPrivileges(_) => { AuthOidcResponse::Forbidden(fe.into()) } - DatabaseError(_) | InternalError(_) => { + DatabaseError(_) | InternalError(_) | DatabaseReadOnly => { error!("{}", fe); capture_fail(&fe); AuthOidcResponse::GenericError(fe.into()) @@ -1322,7 +1322,7 @@ impl Api for Server { InvalidCredentials(_) | InsufficientPrivileges(_) => { AuthCheckResponse::Forbidden(fe.into()) } - DatabaseError(_) | InternalError(_) => { + DatabaseError(_) | InternalError(_) | DatabaseReadOnly => { error!("{}", fe); capture_fail(&fe); AuthCheckResponse::GenericError(fe.into()) @@ -1373,7 +1373,7 @@ impl Api for Server { InvalidCredentials(_) | InsufficientPrivileges(_) => { CreateAuthTokenResponse::Forbidden(fe.into()) } - DatabaseError(_) | InternalError(_) => { + DatabaseError(_) | InternalError(_) | DatabaseReadOnly => { error!("{}", fe); capture_fail(&fe); CreateAuthTokenResponse::GenericError(fe.into()) diff --git a/rust/src/errors.rs b/rust/src/errors.rs index e18e660f..ea0f9646 100644 --- a/rust/src/errors.rs +++ b/rust/src/errors.rs @@ -81,10 +81,13 @@ pub enum FatcatError { // Utf8Decode, StringDecode, Uuid BadRequest(String), - #[fail(display = "unexpected database error: {}", _0)] + #[fail(display = "database error: {}", _0)] // Diesel constraint that we think is a user error ConstraintViolation(String), + #[fail(display = "database in read-only mode (usually replica or maintenance)")] + DatabaseReadOnly, + #[fail(display = "generic database 'not-found'")] // This should generally get caught and handled DatabaseRowNotFound, @@ -117,6 +120,11 @@ impl From for FatcatError { fn from(inner: diesel::result::Error) -> FatcatError { match inner { diesel::result::Error::NotFound => FatcatError::DatabaseRowNotFound, + diesel::result::Error::DatabaseError(_, info) + if info.message().contains("in a read-only transaction") => + { + FatcatError::DatabaseReadOnly + } diesel::result::Error::DatabaseError(_, _) => { FatcatError::ConstraintViolation(inner.to_string()) } -- cgit v1.2.3