在 catch (Exception ex) 中,ex 是例外物件的參考變數,型別為 System.Exception 或其衍生類別。它包含錯誤的完整資訊:
ex.Message:人類可讀的錯誤描述ex.StackTrace:呼叫堆疊,定位拋出位置ex.InnerException:巢狀原始例外(如 SQL 錯誤包裝在 EntityException 中)ex.HResult:錯誤代碼,便於程式化判斷ex.Data:自訂鍵值對,可攜帶額外診斷資訊try {
adapter.Update(ds, "Table");
}
catch (Exception ex) {
MessageBox.Show("修整輪名稱重複"); // 錯誤:忽略 ex 真實資訊
}
正確做法:
catch (Exception ex) {
// 1. 記錄完整資訊供事後分析
Log.Error(ex, "DataGridView 更新失敗");
// 2. 給使用者友善提示,同時保留技術細節
MessageBox.Show($"資料更新失敗:{ex.Message}\n\n詳細資訊已記錄至日誌。", "錯誤");
// 3. 視業務需求決定是否重拋
// throw; // 保留堆疊
}
原始程式碼嘗試手動同步 DataRow,實際上 DataAdapter.Update 已自動處理。正確流程:
private void btnSave_Click(object sender, EventArgs e)
{
try
{
this.Validate(); // 觸發驗證
bindingSource.EndEdit(); // 提交編輯至 DataTable
if (dataSet.HasChanges())
{
int rows = adapter.Update(dataSet, "TableName");
MessageBox.Show($"成功儲存 {rows} 筆變更");
}
}
catch (DbException dbEx) when (dbEx.ErrorCode == -2147217873) // 範例:主鍵重複
{
MessageBox.Show("資料重複,請檢查主鍵欄位。");
}
catch (Exception ex)
{
Log.Error(ex, "儲存失敗");
MessageBox.Show($"儲存失敗:{ex.Message}");
}
}
註解掉的程式碼嘗試手動對應 DataGridView 儲存格到 DataRow,這在繫結架構下是多餘且易錯的。只要正確設定 DataGridView.DataSource = bindingSource,且 bindingSource.DataSource = dataTable,雙向繫結會自動同步。
catch (OleDbException oleEx)
{
switch (oleEx.ErrorCode)
{
case -2147217873: // 80040E2F 主鍵/唯一索引違規
MessageBox.Show("名稱已存在");
break;
case -2147217900: // 80040E14 語法錯誤
MessageBox.Show("SQL 語法錯誤");
break;
default:
MessageBox.Show($"資料庫錯誤:{oleEx.Message}");
break;
}
}
ex 是例外物件,務必使用其屬性(Message、StackTrace、InnerException)進行診斷。Update。ErrorCode 或 Number (SqlException) 給出精準使用者提示。