2012-02-29 30 views
5

Tôi đã tự đào mình vào một lỗ hổng với dự án mà tôi đang làm việc. Tôi đã có dự án khổng lồ này (100 trong số hàng nghìn dòng), và có những lỗi MySQL ở khắp mọi nơi. Tôi đang trong quá trình làm sạch chúng ngay bây giờ.Ném ngoại lệ mà không dừng thực hiện?

Tôi đã có lớp cơ sở dữ liệu này mà tất cả các truy vấn đi qua, vì vậy những gì tôi đã làm là bất cứ khi nào có một lỗi SQL, tôi ném một ngoại lệ ngay bây giờ. Vấn đề là tôi không thể ngừng thực hiện. Nó phải tiếp tục như nó luôn luôn có, và chỉ cần đăng nhập ngoại lệ để tôi có thể theo dõi chúng và sửa chúng từng cái một.

Tôi đã hy vọng set_exception_handler sẽ làm những gì tôi muốn, nhưng các tài liệu đặc biệt nói rằng nó sẽ tạm dừng thực hiện sau khi gọi trình xử lý của tôi. Vì vậy, làm thế nào để tôi có được xung quanh này?

Ngoại lệ có thể tạm dừng chức năng hiện tại, nhưng sau đó tôi muốn nó thoát khỏi hàm, có thể trả về null hoặc false, và sau đó tiếp tục như bình thường, nhưng tôi cần nó để gọi trình xử lý ngoại lệ toàn cục của mình.


Để làm rõ:

Tôi muốn ném một ngoại lệ từ lớp cơ sở dữ liệu của tôi (bất cứ khi nào có một lỗi SQL). Sau đó tôi muốn đăng nhập lỗi này và/hoặc hiển thị thông báo trên màn hình cho đến khi tôi có thể khắc phục lỗi SQL hoặc quấn dòng vi phạm trong lần thử/nắm bắt. Tôi không muốn nó ngừng thực hiện. Nếu tôi chỉ cần gọi một số chức năng error_handler() thay vì ném một ngoại lệ, thì tôi không thể bắt được nó. Nếu tôi nắm bắt nó ngay lập tức (cũng trong lớp DB), thì tôi không thể bắt nó xuống sâu hơn nữa (trừ khi tôi ném lại nó, nhưng sau đó chúng ta quay trở lại để ngừng thực hiện).

+0

Nếu bạn đã cập nhật mã để dịch các lỗi MySQL thành ngoại lệ tại sao không chỉ đăng nhập lỗi thay vì ném một ngoại lệ? – pgraham

+0

@pgraham: Darn nó ... đó là một câu hỏi hay. Lý do là vì tôi muốn có thể bắt được ngoại lệ nếu tôi không muốn nó rơi vào xử lý ngoại lệ toàn cầu. Ngoài ra, tôi muốn có một chức năng xử lý và ghi nhật ký tập trung. Cuối cùng, một khi tôi làm sạch các lỗi, tôi muốn sửa đổi xử lý ngoại lệ toàn cục một chút để nó thực sự * làm * chết và ném một lỗi nghiêm trọng. – mpen

+1

@downvoter: Hãy cẩn thận giải thích tại sao đây là một câu hỏi tồi? – mpen

Trả lời

0

Tôi nghĩ rằng tôi đã tìm thấy giải pháp thay thế. Thay vì ném một ngoại lệ, tôi có thể gọi xử lý của tôi trực tiếp với các ngoại lệ:

global_exception_handler(new MySqlException($error_message)); 

Bằng cách đó xử lý của tôi vẫn được gọi, nhưng thực hiện tiếp tục.

Và sau đó xử lý ngoại lệ tương tự vẫn có thể được sử dụng để bắt tất cả các trường hợp ngoại lệ khác mà thực sự được ném:

function _global_exception_handler($e) { 
    // log error here 
} 

set_exception_handler('global_exception_handler'); 
+0

Nó không phải là một * workaround *. – Alexander

+0

đó là loại giống như thêm một bản in gỡ lỗi, không? – alfasin

1

Nếu tôi đã hiểu bạn một cách chính xác:

function myFunction($params) { 

    try { 

     //your code which throws Exception 

    } catch (Exception $e) { 

     myErrorFunction($e); 
     return false; 
    } 

} 
+0

Không, tôi không nghĩ rằng bạn hiểu đầy đủ các yêu cầu của tôi. Tôi sẽ đặt thử/bắt ở đâu? Tôi không có thời gian để đặt nó xung quanh mọi truy vấn SQL đơn, vì vậy tôi phải đặt nó chính xác nơi tôi ném nó ... nhưng sau đó tôi không thể bắt được nó xuống vì tôi đã bắt được nó . Tôi không nghĩ rằng những gì tôi muốn làm là có thể. – mpen

+0

Bạn có thể bọc toàn bộ mã hoặc chỉ sử dụng nó trong lớp cơ sở dữ liệu của bạn. Bạn có bao nhiêu phương pháp? 10? 20? Chỉ cần quấn chúng với việc thử bắt và mỗi lần bạn thực hiện nó, ví dụ '$ db-> myCustonQuery()', bạn biết rằng nếu có lỗi xảy ra, nó sẽ ném một ngoại lệ mà bạn có thể xử lý ở một nơi khác. Điểm thực của câu trả lời này là nếu bạn 'return false' bạn sẽ có thể tiếp tục thực hiện. – Shoe

+0

Nếu tôi quấn toàn bộ mã, sau đó khi một ngoại lệ được ném, thực thi sẽ thả xuống điểm đó (bắt); Tôi cần nó để tiếp tục khá nhiều nơi nó rời đi (tại ném). Có bao nhiêu phương pháp? Cái gì, trong lớp DB của tôi? 10-20 là một ước tính hợp lý, nhưng việc gói những thứ đó không cho phép tôi bắt nó ở nơi tôi muốn. Về cơ bản tôi muốn * có thể * để nắm bắt tại nơi tôi gọi '$ db-> GetSingleRecord()', nhưng tùy chọn, bởi vì có hàng ngàn cuộc gọi đến chức năng nói và tôi phải đi qua tất cả. Điều đó có ý nghĩa? Tôi nghĩ điều tôi đang hỏi là không thực tế, nhưng đó sẽ là trường hợp tối ưu. – mpen

Các vấn đề liên quan