This article describes the standards that apply to exception handling. All of the listed recommendations are mandatory unless noted otherwise.
In general, we recommend that you do not catch exceptions. In particular, do not catch exceptions solely for displaying error messages, for the platform automatically displays an error message for each uncaught exception.
Still, sometimes you might need to catch exceptions. For example, you might want to modify an error message, making it totally clear for end users. But even if you do, you still have to register the error in the event log to ensure that the system administrator can identify that problem and provide the error details by technical support request.
We recommend that you write the detailed error description to the event log and display a brief description to users.
Examples of incorrect exception handling
1. Some server business logic is called from the client during interactive user work:
&AtServer Procedure PerformAction() // Code that raises an exception ... EndProcedure
Incorrect:
// at client Try PerformAction(); Except DoMessageBox("Cannot perform the action."); EndTry;
Correct:
&AtServer Procedure PerformAction() Try // Code that raises an exception ... Except // Write event log record to be analyzed by system administrator WriteLogEvent(NStr("en = 'Performing action'"), EventLogLevel.Error, , , DetailErrorDescription(ErrorInfo())); Raise; EndTry; EndProcedure
and on the client:
Try PerformAction(); Except MessageText = BriefErrorDescription(ErrorInfo()); DoMessageBox(NStr("en = 'Cannot perform the action. Reason:'" + Chars.LF + MessageText); EndTry;
2. In some client business logic:
&AtClient Procedure CreateFileOnDisk() // Code that raises an exception ... EndProcedure
We recommend that you make an additional server call for registering unsuccessful operation execution in the event log:
Try // Code that raises an exception CreateFileOnDisk(); Except MessageText = BriefErrorDescription(ErrorInfo()); DoMessageBox(NStr("en = 'Cannot perform the action. Reason:'") + Chars.LF + MessageText); WriteFileOperationError(DetailErrorDescription(ErrorInfo())); EndTry; &AtServer Procedure WriteFileOperationError(...) WriteLogEvent(NStr("en = 'Performing action'"), EventLogLevel.Error, , , DetailErrorDescription(ErrorInfo())); EndProcedure
3. Never catch exceptions without notifying the system administrator:
Try // Code that raises an exception ... Except // Catch exceptions EndTry;
As a rule, such script clauses introduce problems that are impossible to locate.
Correct:
Try // Code that raises an exception ... Except // Comment explaining why the exception is caught without notifying end users. // ... // And write an event log record to noify the administrator. WriteLogEvent(NStr("en = 'Performing action'"), EventLogLevel.Error, , , DetailErrorDescription(ErrorInfo())); EndTry;
4. Do not use exceptions for checking the availability of object attributes, methods, templates, and so on. This might lead to errors that are hard to locate, and this also complicates debugging in the "Stop on errors" mode.
Instead of catching exceptions in this scenario we recommed that you:
- Use metadata operations for explicit checks whether an attribute, template, or another piece of data is available.
- If the availability of some data depends on library deployment options, reflect this fact in overridable modules.
- Revise the logic of the methods that catch exceptions. For example, you can implement parameters that define whether some object method or property is accessed.
Incorrect:
Try ContextERPServer.GetTemplate("ExchangeComponent"); Path = ContextERPServer.PathToObject + ".Template.ExchangeComponent"); Except EndTry;
Correct:
ExchangeComponentTemplate = ContextERPServer.Metadata().Templates.Find("ExchangeComponent"); If ExchangeComponentTemplate <> Undefined Then PathToTemplate = ExchangeComponent.FullName(); EndIf;
5. Within transactions, use the following exception handling format:
BeginTransaction(); Try Query = New Query("..."); Selection = Query.Execute().Select(); While Selection.Next() Do ... EndDo; CommitTransaction(); Except RollbackTransaction(); WriteLogEvent(NStr("en = 'Performing action'"), EventLogLevel.Error, , , DetailErrorDescription(ErrorInfo())); Raise; EndTry;
Since an exception does not roll the transaction back immediately but prohibits committing it, each of the BeginTransaction calls must have a matching CommitTransaction or RollbackTransaction call.
Next page: Defining variable value type