2009-04-10 24 views
8

Tôi có một số mã với các trình xử lý lỗi "Lỗi trên Goto" khác nhau ở một vài nơi để xử lý một số phần cứng bên thứ ba bị hỏng. Tôi đã nhận được một lỗi tràn (đọc từ các biến Err) trong một thói quen mà không có một cái bẫy lỗi nhưng được gọi là bởi một thói quen mà không. Tôi luôn nghĩ bẫy lỗi chỉ hợp lệ trong thói quen chúng được khai báo, nhưng có vẻ như một lỗi trong một chương trình con có thể làm cho nó đi đến bẫy lỗi của hàm gọi.Cách bật lại xử lý lỗi mặc định trong VB6

Vì vậy, tôi đã tắt bẫy lỗi của chức năng gọi và tìm thấy tràn của tôi và tất cả đều tốt. Nhưng trước khi tôi làm điều đó, tôi đã dành một chút thời gian để tìm một cách lập trình để VB trở về lỗi xử lý mặc định bên trong thường trình đó (vì vậy tôi sẽ không phải sửa đổi mã bên ngoài để gỡ lỗi), nhưng tôi không thể. Các lệnh lỗi duy nhất tôi có thể tìm thấy:

 On Error GoTo [label] 
    On Error Resume Next 
    On Error Goto 0 
    On Error GoTo -1

tất cả bật xử lý lỗi thủ công - có cách nào tắt nó (trở về mặc định VB6) không?

Trả lời

10

Điều này được giải thích kỹ trong sách hướng dẫn VB6 theo số Error Handling Hierarchy. On Error Goto 0 vô hiệu hóa trình xử lý lỗi trong thủ tục hiện tại, không phải trong quy trình được gọi là xử lý lỗi.

Nếu một lỗi xảy ra trong một thủ tục và thủ tục này không có một kích hoạt xử lý lỗi, Visual Basic tìm kiếm lạc hậu thông qua việc cấp phát thủ tục trong danh sách cuộc gọi - và thực thi xử lý lỗi kích hoạt đầu tiên nó tìm thấy. Nếu số điện thoại không gặp phải lỗi xử lý lỗi được kích hoạt ở bất kỳ đâu trong danh sách cuộc gọi, thì trình bày lỗi không mong muốn mặc định thư và tạm dừng thực thi.

Như những người khác đã nói, bạn có thể vào Tools-Tùy chọn Tổng tab và chọn Nghỉ giải lao trên tất cả các lỗi. Điều đó có hiệu quả vô hiệu hóa tất cả các báo cáo Lỗi của bạn - IDE sẽ phá vỡ ngay lập tức trên mọi lỗi.

Điều đó có thể gây khó chịu nếu mã VB6 của bạn ném lỗi như là một phần của hoạt động bình thường. Ví dụ: khi bạn kiểm tra xem tệp có tồn tại hay khi người dùng nhấn hủy trong cuộc đối thoại chung. Bạn không muốn IDE phá vỡ mọi lúc trên những dòng đó. Nhưng bạn có thể có các trình xử lý lỗi soạn sẵn trong tất cả các thủ tục xử lý sự kiện của bạn, để dừng chương trình gặp lỗi không mong muốn. Nhưng họ là một mối phiền toái khi bạn đang gỡ lỗi các vấn đề vì IDE không phá vỡ dòng với lỗi. Một mẹo là tắt các trình xử lý lỗi đó khi chạy trong IDE, nhưng giữ chúng trong tệp thực thi được xây dựng. Bạn làm như thế này

Thả các chức năng này vào mô-đun.

Public Function InIDE() As Boolean 
    Debug.Assert Not TestIDE(InIDE) 
End Function 

Private Function TestIDE(Test As Boolean) As Boolean 
    Test = True 
End Function 

Sau đó, bạn có thể viết trình xử lý lỗi như thế này.

Private Sub Form_Load() 
    If Not InIDE() Then On Error Goto PreventCrashes 
    <lots of code> 
    Exit Sub 

PreventCrashes: 
    <report the error> 
End Sub 

Bị chèn ép từ here. Một mẹo khác - sử dụng phần bổ sung miễn phí MZTools để tự động thêm các trình xử lý lỗi soạn sẵn này.Đối với mã chất lượng sản xuất, bạn có thể tiến xa hơn và đặt trình xử lý lỗi trong mọi quy trình để tạo một ghetto stack trace. Bạn cũng có thể đăng nhập các lỗi ngay lập tức trong mọi trình xử lý lỗi.

EDIT: Ant đã chỉ ra chính xác rằng On Error Goto -1 là một VB.Net statement và không hợp lệ trong VB6.

EDIT: Arvo và OneNerd đã viết câu trả lời bằng một số cuộc thảo luận thú vị về mô phỏng Cuối cùng các khối ngăn trong xử lý lỗi VB6. Các cuộc thảo luận trong this question cũng đáng xem.

0

/Tools/Options/General/Xử lý lỗi

0
on error goto 0 

nên được những gì bạn muốn ... Nó nên gây ra lỗi cho ném, và lần lượt có thể thư giãn đến RTL ...

Đã lâu rồi, nhưng tôi khá chắc chắn đó là những gì bạn muốn.

on error resume next 

sẽ chỉ tiếp tục báo cáo kết quả tiếp theo, vì vậy bạn cần phải có nhiều

if err.Number <> 0 then 

báo cáo trong mã của bạn, nơi các lỗi có thể xảy ra ...

+0

Không chính xác LarryF. Trên Error Goto 0 vô hiệu hóa trình xử lý lỗi trong chính thường trình, nhưng sau đó thời gian chạy sẽ xem lại ngăn xếp cuộc gọi cho bất kỳ trình xử lý lỗi hoạt động nào. Nếu có, nó sẽ xử lý lỗi. – MarkJ

+0

Opps .. xấu của tôi. Tôi đã phải suy nghĩ của vbScript, mà sẽ cư xử như mô tả .. Hoặc, ít nhất là nó được sử dụng để. (Tôi không biết phiên bản mới nhất là gì, và nếu nó thậm chí còn thay đổi gần đây ..) – LarryF

1

Có một tên bên phải tiện dụng nhấp vào menu cho phép bạn bật và tắt xử lý lỗi. Chỉ cần nhấp chuột phải vào một cửa sổ mã và chọn Toggle, sau đó bạn có thể chọn "Break on all errors". Điều này sẽ có tác dụng vô hiệu hóa tất cả các báo cáo "On Error" của bạn.

0

Phải đồng ý với LarryF, On Error GoTo 0 nên tắt rõ ràng lỗi xử lý đã được bật theo On Error Resume Next. Các hàm và các chương trình con có phạm vi riêng của chúng cho điều này. Từ Dr. Scripto at Microsoft:

Đưa On Error Resume Next ở đầu của kịch bản, như chúng ta thường làm, làm cho nó áp dụng cho toàn bộ cơ thể của kịch bản. Nhưng, như chúng ta sẽ thấy trong ví dụ sau , phạm vi của nó không bao gồm các hàm hoặc chương trình con. Nếu bạn muốn xử lý lỗi trong một hàm hoặc chương trình con , bạn cũng phải bao gồm khi lỗi tiếp tục tiếp theo trong mỗi của chúng trước khi kiểm tra đối tượng Err .

Bạn có thể bật lỗi xử lý ra với On Error GoTo 0. Vì vậy, nó có thể lượt lỗi xử lý trên với On Error Resume Next ngay trước khi bạn muốn kiểm tra các đối tượng Err, và tắt nó đi sau với On Error GoTo 0.

+0

Erm, nhưng Tiến sĩ Scripto đang nói về VBScript, và câu hỏi là về VB6 – MarkJ

1

Dưới đây là những gì tôi làm:

lượt đầu tiên về lỗi xử lý như thế này nếu cần thiết trong bạn Sub Main() hoặc Sub Form_Load() Sub:

'-- turn on error handling 
' 
On Error GoTo 0 
' 
'------------------------- 

Bây giờ lỗi sẽ được bật.

Tiếp theo, Sử dụng On Error Resume NextOn Error GoTo {label} lệnh kết hợp với các đối tượngErr. Dưới đây là ví dụ về mô phỏng thử/bắt/cuối cùng:

Function MyFunction() as String 

'-- start of error block 
' 
On Error Goto Catch 
    ' do something here that might cause an error 
    MyFunction = "IT WORKED" 
    Goto Finally 

    Catch: 
    ' error occured - do something else 
    MyFunction = Err.Description 
    Err.Clear 

Finally: 
    ' put your finally code here 

' 
'-- end of error block 

End Function 
+0

+1 Bạn có thể cần Ngày Tiếp tục Lỗi Tiếp theo trong "Cuối cùng" chặn trong trường hợp lỗi gây trở ngại cho việc thiết lập bất kỳ nhu cầu nào xé xuống. Và tôi không hiểu tại sao bạn đã đặt On Error Goto 0 trong Form_Load/Sub Main? – MarkJ

0

Không có "On Error GoTo -1" vì vậy tôi không biết bạn đã nhận được điều đó ở đâu.

Xử lý ngoại lệ VB6 được trình bày rất kỹ trong hướng dẫn sử dụng.

+1

Tôi nghĩ rằng đó là một tuyên bố VB.NET: http://msdn.microsoft.com/en-us/library/5hsw66as(VS.80).aspx – Ant

3

Có cách rõ ràng và đơn giản để đặt lại trạng thái lỗi - sử dụng từ khóa Tiếp tục. Có ba khả năng:

Resume 
Resume Next 
Resume <Label> 

Tiếp tục tiếp tục thực hiện tại dòng errored, Resume Next ở dòng tiếp theo và ít nói chuyện Resume Label tiếp tục ở nhãn. Rất hữu ích để tạo try-catch-finally giống như các cấu trúc trong VB6. Vay và sửa đổi từ câu trả lời OneNerd:

Function MyFunction() as String 

'-- start of error block 
' 
On Error Goto Catch 
    ' do something here that might cause an error 
    MyFunction = "IT WORKED" 
    Goto Finally 

    Catch: 
    ' error occured - do something else 
    MyFunction = Err.Description 
    Err.Clear 
    Resume Finally   ''added to clear error status 

Finally: 
    On Error Resume Next ''added to avoid repeated errors 
    ' put your finally code here 

' 
'-- end of error block 

End Function 

Err.Clear đơn giản không giúp, nếu một số lỗi sau xảy ra trong khối Cuối cùng; Resume Cuối cùng, thiết lập lại trạng thái lỗi nội bộ.

+0

Khi tiếp tục lỗi Tiếp theo cũng đặt lại trạng thái lỗi nội bộ để Err.Clear và Tiếp tục Cuối cùng là dư thừa. Cá nhân nghĩ rằng Goto Cuối cùng là rõ ràng hơn. Quan trọng nhất là đặt Err.Clear hoặc On Error Goto 0 ngay trước End Function nếu không thì bất kỳ trạng thái lỗi nào từ cuối cùng sẽ trở lại người gọi !! – MarkJ

+0

Lỗi khi tiếp tục Tự động tiếp theo (sau khi lỗi) không đặt lại trạng thái lỗi. Tôi chỉ thử nghiệm là chắc chắn 100%. – Arvo

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