Cách xác định xem ngoại lệ có thuộc một loại cụ thể không


82

Tôi có một đoạn mã thử bắt:

try 
{
    ...
}
catch(Exception ex) 
{
    ModelState.AddModelError(
        "duplicateInvoiceNumberOrganisation", "The combination of organisation and invoice number must be unique");
}

Đối với đoạn mã này, tôi đang cố gắng chèn một bản ghi vào cơ sở dữ liệu: dba đã thiết lập nó để cơ sở dữ liệu kiểm tra các bản sao và trả về lỗi nếu có các bản sao. Hiện tại, như bạn có thể thấy, tôi đang thêm cùng một lỗi vào mô hình bất kể lỗi nào xảy ra. Tôi muốn nó thay đổi vì vậy lỗi này chỉ được thêm vào mô hình nếu nó là do lỗi trùng lặp do dba thiết lập.

Dưới đây là lỗi tôi muốn bắt. Lưu ý rằng nó nằm trong ngoại lệ bên trong. Bất cứ ai có thể cho tôi biết làm thế nào để bắt cụ thể một trong những điều này?

nhập mô tả hình ảnh ở đây


1
Hãy xem câu trả lời của Davide. Nói chung đánh bắt Exceptionkhông phải là cách tốt nhất. Bạn nên càng cụ thể càng tốt và để bất cứ thứ gì bạn không thể xử lý bong bóng cho người dùng / khuôn khổ.
Ryan

1
Hãy xem câu trả lời này: stackoverflow.com/questions/3967140/…
Rob Packwood,

Câu trả lời:


141

trước khi bắt hiện tại của bạn, hãy thêm những thứ sau:

catch(DbUpdateException ex)
{
  if(ex.InnerException is UpdateException)
  {
    // do what you want with ex.InnerException...
  }
}

Từ C # 6, bạn có thể làm như sau:

catch(DbUpdateException ex) when (ex.InnerException is UpdateException)
{
    // do what you want with ex.InnerException...
}

3
có cú pháp bắt "khi không" không?
Conterio

4
@conteriocatch(DbUpdateException ex) when (!(ex.InnerException is UpdateException))
Tom

16

Thay thế System.Threading.ThreadAbortExceptionbằng ngoại lệ của bạn.

try
{
    //assume ThreadAbortException occurs here
}
catch (Exception ex)
{
    if (ex.GetType().IsAssignableFrom(typeof(System.Threading.ThreadAbortException)))
    {
         //what you want to do when ThreadAbortException occurs         
    }
    else
    {
         //do when other exceptions occur
    }
}

3

Để lấy tên của ngoại lệ, bạn có thể sử dụng

    catch (Exception exc){
       if (exc.GetType().FullName == "Your_Exception") 
       {
          // The same can be user for InnerExceptions
          // exc.InnerException.GetType().FullName
       }
   }

2
So sánh loại ngoại lệ theo chuỗi là nguy hiểm. Một lỗi chính tả đáng tiếc sẽ khiến việc xử lý ngoại lệ trở thành một cơn ác mộng!
Tejas Pendse

Đã đồng ý. So sánh Loại với Loại. exc.GetType () == typeof (YourException)
Lee Oades

2

Không đủ đại diện để bình luận. Để trả lời câu hỏi của @conterio (trong câu trả lời của @Davide Piras):

có cú pháp bắt "khi không" không?

Có.

catch (Exception e) when (!(e is ArgumentException)) { }

-3

Bạn có thể xem qua lớp SQLException - và kiểm tra nội dung của thông báo của ngoại lệ nếu nó chứa những gì bạn thấy trong ngoại lệ bên trong của mình..Một cái gì đó như thế này:

try
{
    //your code here
}
catch (SQLException ex)
{
    if (ex.Message.Contains("Cannot insert duplicate key in obj...."))
    {
        //your code here
    }
}

1
Tôi nghi ngờ rằng SqlException được ném trực tiếp, nhưng chỉ như một ngoại lệ bên trong. Ngoài ra, có lẽ sẽ tốt hơn nếu kiểm tra số lỗi hơn là so sánh với văn bản tin nhắn.
John Saunders

Đúng vậy, bạn cũng có thể kiểm tra số lỗi. Cảm ơn đã nhận xét.
Ann BG

Làm thế nào để bạn kiểm tra số lỗi? Tôi thậm chí không chắc số đó là gì vì đó là một lỗi thực sự cụ thể?
AnonyMouse
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.