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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user