Better error handling
This commit is contained in:
parent
425e00acc1
commit
dcaa920c51
@ -18,10 +18,12 @@ use tracing::info;
|
||||
#[derive(Debug)]
|
||||
pub struct DatabaseError {
|
||||
long: String,
|
||||
#[allow(dead_code)]
|
||||
short: String,
|
||||
}
|
||||
|
||||
impl DatabaseError {
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
pub fn new<S, T>(long: S, short: T) -> Self
|
||||
where
|
||||
T: ToString,
|
||||
|
@ -1,10 +1,15 @@
|
||||
use super::super::schema;
|
||||
use crate::{db::Database, graphql::Context};
|
||||
use crate::{
|
||||
db::{Database, DatabaseError},
|
||||
graphql::Context,
|
||||
};
|
||||
use diesel::prelude::*;
|
||||
use juniper::GraphQLEnum;
|
||||
use juniper::{FieldResult, GraphQLEnum};
|
||||
use schema::{wordrelation, words};
|
||||
use tracing::info;
|
||||
|
||||
use std::convert::Into;
|
||||
|
||||
use super::languages::Language;
|
||||
|
||||
#[derive(diesel_derive_enum::DbEnum, Debug, Clone, PartialEq, Eq)]
|
||||
@ -62,24 +67,29 @@ impl Word {
|
||||
&self,
|
||||
db: &Database,
|
||||
relationship: WordRelationship,
|
||||
) -> Vec<Word> {
|
||||
) -> Result<Vec<Word>, DatabaseError> {
|
||||
use schema::wordrelation::dsl;
|
||||
match &mut db.conn() {
|
||||
Ok(conn) => dsl::wordrelation
|
||||
Ok(conn) => Ok(dsl::wordrelation
|
||||
.filter(dsl::wordsource.eq(self.norm.clone()))
|
||||
.filter(dsl::relationship.eq(relationship))
|
||||
.load::<WordRelation>(conn)
|
||||
.unwrap()
|
||||
.map_err(|e| {
|
||||
DatabaseError::new(
|
||||
format!("Failed to retrieve word relations: {:?}", e),
|
||||
"Database reading failed",
|
||||
)
|
||||
})?
|
||||
.into_iter()
|
||||
.flat_map(|w| {
|
||||
use schema::words::dsl;
|
||||
dsl::words.find(w.wordtarget).first::<Word>(conn)
|
||||
})
|
||||
.collect::<Vec<Word>>(),
|
||||
Err(e) => {
|
||||
info!("Could not connect to database: {:?}", e);
|
||||
Vec::new()
|
||||
}
|
||||
.collect::<Vec<Word>>()),
|
||||
Err(e) => Err(DatabaseError::new(
|
||||
format!("Failed to connect to the database: {:?}", e),
|
||||
"Database connection error",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -185,16 +195,18 @@ impl Word {
|
||||
name = "related",
|
||||
description = "Words related to the current word"
|
||||
)]
|
||||
fn related_words(&self, context: &Context) -> Vec<Word> {
|
||||
fn related_words(&self, context: &Context) -> FieldResult<Vec<Word>> {
|
||||
self.relationship(&context.db, WordRelationship::Related)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
|
||||
#[graphql(
|
||||
name = "definitions",
|
||||
description = "Words that define the current word"
|
||||
)]
|
||||
fn definitions(&self, context: &Context) -> Vec<Word> {
|
||||
fn definitions(&self, context: &Context) -> FieldResult<Vec<Word>> {
|
||||
self.relationship(&context.db, WordRelationship::Definition)
|
||||
.map_err(Into::into)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,10 @@
|
||||
use juniper::FieldResult;
|
||||
|
||||
use super::Context;
|
||||
use crate::db::{models::{languages::Language, users::User, words::Word}, DatabaseError};
|
||||
use crate::db::{
|
||||
models::{languages::Language, users::User, words::Word},
|
||||
DatabaseError,
|
||||
};
|
||||
|
||||
use std::str::FromStr;
|
||||
|
||||
@ -16,15 +19,19 @@ impl Query {
|
||||
name = "allLanguages",
|
||||
description = "Retrieve all languages defined in the database"
|
||||
)]
|
||||
fn all_languages(context: &Context) -> Vec<Language> {
|
||||
context.db.all_languages().unwrap()
|
||||
fn all_languages(context: &Context) -> FieldResult<Vec<Language>> {
|
||||
context.db.all_languages().map_err(Into::into)
|
||||
}
|
||||
|
||||
fn all_users(context: &Context, admin_key: String) -> FieldResult<Vec<User>> {
|
||||
fn all_users(
|
||||
context: &Context,
|
||||
admin_key: String,
|
||||
) -> FieldResult<Vec<User>> {
|
||||
if admin_key == context.other_vars.admin_key {
|
||||
context.db.all_users().map_err(Into::into)
|
||||
} else {
|
||||
Err(DatabaseError::new("Invalid admin key", "Invalid admin key").into())
|
||||
Err(DatabaseError::new("Invalid admin key", "Invalid admin key")
|
||||
.into())
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,9 +76,21 @@ impl Query {
|
||||
word(description = "Word to search")
|
||||
)
|
||||
)]
|
||||
fn words(context: &Context, language: String, word: String) -> Vec<Word> {
|
||||
context
|
||||
.db
|
||||
.words(uuid::Uuid::from_str(&language).unwrap(), word.as_str())
|
||||
fn words(
|
||||
context: &Context,
|
||||
language: String,
|
||||
word: String,
|
||||
) -> FieldResult<Vec<Word>> {
|
||||
match uuid::Uuid::from_str(&language) {
|
||||
Ok(uuid) => Ok(context.db.words(uuid, word.as_str())),
|
||||
Err(e) => Err(DatabaseError::new(
|
||||
format!(
|
||||
"Failed to convert {} to a proper UUID: {:?}",
|
||||
language, e
|
||||
),
|
||||
"Conversion Error",
|
||||
)
|
||||
.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user