Skip to content

Commit 9dfb831

Browse files
committed
improved error handling
1 parent 897e1a1 commit 9dfb831

File tree

4 files changed

+92
-30
lines changed

4 files changed

+92
-30
lines changed

src/ts_generator/errors.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@ pub enum TsGeneratorError {
3434
UnknownErrorWhileProcessingTableWithJoins(String),
3535
#[error("[E015] Table expressions are not supported in INSERT statements - query: `{0}`")]
3636
TableExpressionInInsertStatement(String),
37+
#[error("[E016] Column '{column}' not found in table '{table}'. Available columns: {available_columns}")]
38+
ColumnNotFoundInTable {
39+
column: String,
40+
table: String,
41+
available_columns: String,
42+
},
43+
#[error("[E017] Failed to process INSERT statement: {reason}. Query: `{query}`")]
44+
InsertStatementProcessingFailed { reason: String, query: String },
45+
#[error("[E018] Table '{table}' not found in database schema. Check that the table exists and is accessible.")]
46+
TableNotFoundInSchema { table: String },
47+
#[error("[E019] Failed to infer table name while processing WHERE clause. Query: `{query}`")]
48+
TableNameInferenceFailedInWhere { query: String },
49+
#[error("[E020] Invalid column reference '{column}' for table '{table}'. Ensure the column exists in the table schema.")]
50+
InvalidColumnReference { column: String, table: String },
3751
#[error("Unknown error: `{0}`")]
3852
Unknown(String),
3953
}

src/ts_generator/sql_parser/expressions/translate_expr.rs

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,11 @@ pub async fn get_sql_query_param(
132132
} else if single_table_name.is_some() {
133133
table_name = single_table_name.map(|x| x.to_string());
134134
} else {
135-
panic!("failed to find an appropriate table name while processing WHERE statement")
135+
error!(
136+
"Failed to infer table name while processing WHERE clause. Expression: {}",
137+
left
138+
);
139+
return None;
136140
}
137141

138142
let column_name = translate_column_name_expr(left);
@@ -148,13 +152,30 @@ pub async fn get_sql_query_param(
148152
.lock()
149153
.await
150154
.fetch_table(&table_names, db_conn)
151-
.await
152-
.unwrap_or_else(|| panic!("Failed to fetch columns for table {table_name}"));
155+
.await;
156+
157+
if columns.is_none() {
158+
error!(
159+
"Table '{}' not found in database schema. Check that the table exists and is accessible.",
160+
table_name
161+
);
162+
return None;
163+
}
164+
165+
let columns = columns.unwrap();
153166

154167
// get column and return TsFieldType
155-
let column = columns
156-
.get(column_name.as_str())
157-
.unwrap_or_else(|| panic!("Failed to find the column from the table schema of {table_name}"));
168+
let column = columns.get(column_name.as_str());
169+
if column.is_none() {
170+
let available_columns = columns.keys().map(|k| k.as_str()).collect::<Vec<_>>().join(", ");
171+
error!(
172+
"Column '{}' not found in table '{}'. Available columns: {}",
173+
column_name, table_name, available_columns
174+
);
175+
return None;
176+
}
177+
178+
let column = column.unwrap();
158179
Some((column.field_type.to_owned(), column.is_nullable, Some(expr_placeholder)))
159180
}
160181
_ => None,
@@ -731,16 +752,35 @@ pub async fn translate_assignment(
731752
let value = get_expr_placeholder(&assignment.value);
732753

733754
if value.is_some() {
734-
let table_details = &DB_SCHEMA
755+
let table_details = DB_SCHEMA
735756
.lock()
736757
.await
737758
.fetch_table(&vec![table_name], db_conn)
738759
.await
739-
.unwrap();
740-
let column_name = translate_column_name_assignment(assignment).unwrap();
741-
let field = table_details
742-
.get(&column_name)
743-
.unwrap_or_else(|| panic!("Failed to find the column detail for {column_name}"));
760+
.ok_or_else(|| TsGeneratorError::TableNotFoundInSchema {
761+
table: table_name.to_string(),
762+
})?;
763+
764+
let column_name = translate_column_name_assignment(assignment).ok_or_else(|| {
765+
TsGeneratorError::InsertStatementProcessingFailed {
766+
reason: "Failed to extract column name from assignment".to_string(),
767+
query: format!("UPDATE {} SET {} = ...", table_name, assignment),
768+
}
769+
})?;
770+
771+
let field = table_details.get(&column_name).ok_or_else(|| {
772+
let available_columns = table_details
773+
.keys()
774+
.map(|k| k.as_str())
775+
.collect::<Vec<_>>()
776+
.join(", ");
777+
TsGeneratorError::ColumnNotFoundInTable {
778+
column: column_name.clone(),
779+
table: table_name.to_string(),
780+
available_columns,
781+
}
782+
})?;
783+
744784
let _ = ts_query.insert_param(&field.field_type, &field.is_nullable, &value);
745785
}
746786
Ok(())

src/ts_generator/sql_parser/translate_insert.rs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,24 +41,28 @@ pub async fn translate_insert(
4141
if placeholder.is_some() {
4242
let match_col = &columns
4343
.get(column)
44-
.unwrap_or_else(|| {
45-
panic!(
46-
r#"
47-
Failed to process values of insert statement as column names are not provided or incorrectly specified
48-
49-
Try specifying column names
50-
```
51-
INSERT INTO table_name (column1, column2, column3, ...)
52-
VALUES (value1, value2, value3, ...);
53-
```
54-
"#
55-
)
56-
})
44+
.ok_or_else(|| {
45+
TsGeneratorError::InsertStatementProcessingFailed {
46+
reason: format!(
47+
"Column at position {} is not provided in the column list. Expected {} columns but found {} values.",
48+
column, columns.len(), values.len()
49+
),
50+
query: format!(
51+
"INSERT INTO {} VALUES (...). Try specifying column names explicitly: INSERT INTO {} (column1, column2, ...) VALUES (...)",
52+
table_name, table_name
53+
),
54+
}
55+
})?
5756
.value;
5857

59-
let field = table_details
60-
.get(match_col.as_str())
61-
.unwrap_or_else(|| panic!("Column {match_col} is not found while processing insert params"));
58+
let field = table_details.get(match_col.as_str()).ok_or_else(|| {
59+
let available_columns = table_details.keys().map(|k| k.as_str()).collect::<Vec<_>>().join(", ");
60+
TsGeneratorError::ColumnNotFoundInTable {
61+
column: match_col.clone(),
62+
table: table_name.to_string(),
63+
available_columns,
64+
}
65+
})?;
6266

6367
if value.to_string() == "?" {
6468
// If the placeholder is `'?'`, we can process it using insert_value_params and generate nested params type

src/ts_generator/sql_parser/translate_query.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,12 @@ pub async fn translate_select(
123123
let mut table_name: Option<&str> = None;
124124
if full_table_with_joins.is_some() && !full_table_with_joins.as_ref().unwrap().is_empty() {
125125
table_name_owned = Some(
126-
translate_table_with_joins(full_table_with_joins, &select_item)
127-
.unwrap_or_else(|_| panic!("{}", format!("Default FROM table is not found from the query {select}"))),
126+
translate_table_with_joins(full_table_with_joins, &select_item).map_err(|_| {
127+
TsGeneratorError::UnknownErrorWhileProcessingTableWithJoins(format!(
128+
"Default FROM table is not found from the query: {}. Ensure your query has a valid FROM clause.",
129+
select
130+
))
131+
})?,
128132
);
129133
table_name = table_name_owned.as_deref();
130134
}

0 commit comments

Comments
 (0)