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