1
0
mirror of https://github.com/1C-Company/v8-code-style.git synced 2024-11-28 09:33:06 +02:00

#394 Реализована проверка ПустойБлокИсключения (#447)

This commit is contained in:
EightM 2021-09-10 16:39:27 +03:00 committed by GitHub
parent 76b3ade944
commit 5ef16e6dfb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 361 additions and 2 deletions

View File

@ -31,6 +31,7 @@
- Проверка конструктора структуры содержащего больше 3х ключей
- Выполнение запроса в цикле с учетом локальных вызовов в модуле
- Проверка ОбменДанными.Загрузка в обработчике события
- Конструкция "Попытка...Исключение...КонецПопытки" не содержит кода в исключении
#### Запросы

View File

@ -0,0 +1,45 @@
# Empty except statement
It is incorrect to hide the issue from the user and administrator. We recommend that you write
a detailed exception presentation to the event log and add a short presentation to a user message.
## Noncompliant Code Example
```bsl
Try
ExecuteOperation();
Except
// error;
EndTry;
```
## Compliant Code Example
```bsl
Try
// Code that throws an exception
....
Except
// Writing an event to the event log for the system administrator.
WriteLogEvent(NStr("en = 'Executing an operation'"),
EventLogLevel.Error,,,
DetailErrorDescription(ErrorInfo()));
Raise;
EndTry;
```
## Suppress check
Also you can suppress check on try-except statement and leave the clear message:
```bsl
// @skip-check empty-except-statement - suppress because...
Try
...
Except
EndTry;
```
## See
- [Catching exceptions in code](https://support.1ci.com/hc/en-us/articles/360011002440-Catching-exceptions-in-code)

View File

@ -0,0 +1,49 @@
# Конструкция "Попытка...Исключение...КонецПопытки" не содержит кода в исключении
Недопустимо перехватывать любые исключения, бесследно для системного
администратора.
Как правило, подобная конструкция скрывает реальную проблему, которую
впоследствии невозможно диагностировать.
## Неправильно
```bsl
Попытка
// код, приводящий к вызову исключения
....
Исключение // перехват любых исключений
КонецПопытки;
```
## Правильно
```bsl
Попытка
// код, приводящий к вызову исключения
....
Исключение
// Пояснение причин перехвата всех исключений "незаметно" от пользователя.
// ....
// И запись события в журнал регистрации для системного администратора.
ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
```
## Подавление проверки
В случаях когда отсутствующий код в блоке исключения является особенностью проектирования, есть возможность
подавить срабатывание проверки на конкретном выражении и оставить поясняющий комментарий:
```bsl
// @skip-check empty-except-statement - не отлавливаем исключение потому что...
Попытка
...
Исключение
КонецПопытки;
```
## См.
- [Перехват исключений в коде](https://its.1c.ru/db/v8std#content:499:hdoc:2)

View File

@ -36,6 +36,10 @@
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.internal.bsl.ExecutableExtensionFactory:com.e1c.v8codestyle.bsl.check.EventDataExchangeLoadCheck">
</check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.bsl.check.EmptyExceptStatementCheck">
</check>
</extension>

View File

@ -0,0 +1,77 @@
/*******************************************************************************
* Copyright (C) 2021, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Viktor Gukov - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.TRY_EXCEPT_STATEMENT;
import java.util.Optional;
import org.eclipse.core.runtime.IProgressMonitor;
import com._1c.g5.v8.dt.bsl.model.TryExceptStatement;
import com.e1c.g5.v8.dt.check.CheckComplexity;
import com.e1c.g5.v8.dt.check.ICheckParameters;
import com.e1c.g5.v8.dt.check.components.BasicCheck;
import com.e1c.g5.v8.dt.check.settings.IssueSeverity;
import com.e1c.g5.v8.dt.check.settings.IssueType;
import java.util.List;
/**
* Checks try-except-endtry statements, for empty except statement.
*
* @author Viktor Gukov
*
*/
public class EmptyExceptStatementCheck
extends BasicCheck
{
private static final String CHECK_ID = "empty-except-statement";
@Override
public String getCheckId()
{
return CHECK_ID;
}
@Override
protected void check(Object object, ResultAcceptor acceptor, ICheckParameters parameters, IProgressMonitor monitor)
{
if (monitor.isCanceled())
{
return;
}
TryExceptStatement tryExceptStatement = TryExceptStatement.class.cast(object);
Optional.of(tryExceptStatement)
.map(TryExceptStatement::getExceptStatements)
.filter(List::isEmpty)
.ifPresent(list -> acceptor.addIssue(Messages.EmptyExceptStatementCheck_description, tryExceptStatement));
}
@Override
protected void configureCheck(CheckConfigurer configurer)
{
configurer.title(Messages.EmptyExceptStatementCheck_title)
.description(Messages.EmptyExceptStatementCheck_description)
.complexity(CheckComplexity.NORMAL)
.severity(IssueSeverity.MINOR)
.issueType(IssueType.CODE_STYLE)
.module()
.checkedObjectType(TRY_EXCEPT_STATEMENT);
}
}

View File

@ -49,6 +49,11 @@ final class Messages
public static String StructureCtorTooManyKeysCheck_Maximum_structure_constructor_keys;
public static String StructureCtorTooManyKeysCheck_Structure_constructor_has_more_than__0__keys;
public static String StructureCtorTooManyKeysCheck_title;
public static String EmptyExceptStatementCheck_title;
public static String EmptyExceptStatementCheck_description;
static
{

View File

@ -1,4 +1,3 @@
#Generated by ResourceBundle Editor (http://essiembre.github.io/eclipse-rbe/)
###############################################################################
# Copyright (C) 2021, 1C-Soft LLC and others.
@ -12,12 +11,18 @@
# Contributors:
# 1C-Soft LLC - initial API and implementation
# Aleksandr Kapralov - issue #17
# Viktor Gukov - issue #394
###############################################################################
EmptyExceptStatementCheck_description = Empty except statement
EmptyExceptStatementCheck_title = Empty except statement
EventDataExchangeLoadCheck_Check_at_the_beginning_of_event_handler = Check at the beginning of event handler
EventDataExchangeLoadCheck_Function_list_that_checks_DataExchange_Load = Function list that checks DataExchange.Load
EventDataExchangeLoadCheck_Mandatory_checking_of_DataExchangeLoad_is_absent_in_event_handler_0=Mandatory checking of "DataExchange.Load" is absent in event handler "{0}"
EventDataExchangeLoadCheck_Mandatory_checking_of_DataExchangeLoad_is_absent_in_event_handler_0 = Mandatory checking of "DataExchange.Load" is absent in event handler "{0}"
EventDataExchangeLoadCheck_No_return_in__DataExchange_Load__checking = No Return in "DataExchange.Load" checking

View File

@ -11,8 +11,13 @@
# Contributors:
# 1C-Soft LLC - initial API and implementation
# Aleksandr Kapralov - issue #17
# Viktor Gukov - issue #394
###############################################################################
EmptyExceptStatementCheck_description = "Попытка...Исключение" не содержит кода в исключении
EmptyExceptStatementCheck_title = "Попытка...Исключение" не содержит кода в исключении
EventDataExchangeLoadCheck_Check_at_the_beginning_of_event_handler = Проверять в начале обработка события
EventDataExchangeLoadCheck_Function_list_that_checks_DataExchange_Load = Список функций проверяющие ОбменДанными.Загрузка

View File

@ -0,0 +1,81 @@
/*******************************************************************************
* Copyright (C) 2021, 1C-Soft LLC and others.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Viktor Gukov - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check.itests;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.eclipse.emf.common.util.EList;
import org.junit.Test;
import com._1c.g5.v8.bm.core.IBmObject;
import com._1c.g5.v8.dt.bsl.model.Method;
import com._1c.g5.v8.dt.bsl.model.Module;
import com._1c.g5.v8.dt.bsl.model.Statement;
import com._1c.g5.v8.dt.bsl.model.TryExceptStatement;
import com._1c.g5.v8.dt.core.platform.IDtProject;
import com._1c.g5.v8.dt.metadata.mdclass.CommonModule;
import com._1c.g5.v8.dt.validation.marker.Marker;
import com.e1c.g5.v8.dt.testing.check.CheckTestBase;
import com.e1c.v8codestyle.bsl.check.EmptyExceptStatementCheck;
/**
* Tests for {@link EmptyExceptStatementCheck} check.
*
* @author Viktor Gukov
*
*/
public class EmptyExceptStatementCheckTest
extends CheckTestBase
{
private static final String PROJECT_NAME = "EmptyExceptStatement";
private static final String CHECK_ID = "empty-except-statement";
private static final String FQN_MODULE_GENERAL = "CommonModule.ОбщийМодуль1";
/**
* Test common module methods for empty except statements
*
* @throws Exception
*/
@Test
public void testEmptyExceptStatement() throws Exception
{
IDtProject dtProject = openProjectAndWaitForValidationFinish(PROJECT_NAME);
assertNotNull(dtProject);
IBmObject mdObject = getTopObjectByFqn(FQN_MODULE_GENERAL, dtProject);
assertTrue(mdObject instanceof CommonModule);
Module module = ((CommonModule)mdObject).getModule();
assertNotNull(module);
EList<Method> methods = module.allMethods();
assertEquals(2, methods.size());
Method badMethod = methods.get(0);
EList<Statement> methodStatements = badMethod.allStatements();
assertEquals(1, methodStatements.size());
Statement statement = methodStatements.get(0);
assertTrue(statement instanceof TryExceptStatement);
TryExceptStatement tryExceptStatement = TryExceptStatement.class.cast(statement);
getFirstMarker(CHECK_ID, tryExceptStatement, dtProject);
Marker marker = getFirstMarker(CHECK_ID, tryExceptStatement, dtProject);
assertNotNull(marker);
assertEquals("2", marker.getExtraInfo().get("line"));
}
}

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>EmptyExceptStatement</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com._1c.g5.v8.dt.core.V8ConfigurationNature</nature>
<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -0,0 +1,2 @@
Runtime-Version: 8.3.19
Manifest-Version: 1.0

View File

@ -0,0 +1,21 @@
Процедура ПлохойКейс()
Попытка
// код, приводящий к вызову исключения
Исключение
// нарушение стандарта
КонецПопытки;
КонецПроцедуры
Процедура ХорошийКейс()
Попытка
// код, приводящий к вызову исключения
Исключение
// Пояснение причин перехвата всех исключений "незаметно" от пользователя.
// ....
// И запись события в журнал регистрации для системного администратора.
ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
УровеньЖурналаРегистрации.Ошибка,,,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецПроцедуры

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:CommonModule xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="12030016-c739-4dfa-9b4e-65b3b4c2846c">
<name>ОбщийМодуль1</name>
<server>true</server>
</mdclass:CommonModule>

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<mdclass:Configuration xmlns:mdclass="http://g5.1c.ru/v8/dt/metadata/mdclass" uuid="e6cdff71-a60a-47d9-9dfd-35abf4b5ce9b">
<name>Конфигурация</name>
<containedObjects classId="9cd510cd-abfc-11d4-9434-004095e12fc7" objectId="e10743ce-d133-4ce1-a1b0-717c178be7ce"/>
<containedObjects classId="9fcd25a0-4822-11d4-9414-008048da11f9" objectId="08a6b74a-1156-41d7-b03f-a09fe099eea5"/>
<containedObjects classId="e3687481-0a87-462c-a166-9f34594f9bba" objectId="e4ae6325-f6fd-4b12-be21-5062ac604d5f"/>
<containedObjects classId="9de14907-ec23-4a07-96f0-85521cb6b53b" objectId="5a43c58b-7f3a-4970-8caa-0ca5291ae0f4"/>
<containedObjects classId="51f2d5d8-ea4d-4064-8892-82951750031e" objectId="03b2a921-5da2-48f8-ba26-be422e5b6a49"/>
<containedObjects classId="e68182ea-4237-4383-967f-90c1e3370bc7" objectId="4ddf7c47-4106-45a6-b4df-77f95e4ec743"/>
<containedObjects classId="fb282519-d103-4dd3-bc12-cb271d631dfc" objectId="acd01b34-0551-4ccb-83fa-740a3fc03796"/>
<configurationExtensionCompatibilityMode>8.3.19</configurationExtensionCompatibilityMode>
<defaultRunMode>ManagedApplication</defaultRunMode>
<usePurposes>PersonalComputer</usePurposes>
<scriptVariant>Russian</scriptVariant>
<usedMobileApplicationFunctionalities>
<functionality>
<use>true</use>
</functionality>
<functionality>
<functionality>OSBackup</functionality>
<use>true</use>
</functionality>
</usedMobileApplicationFunctionalities>
<defaultLanguage>Language.Русский</defaultLanguage>
<dataLockControlMode>Managed</dataLockControlMode>
<objectAutonumerationMode>NotAutoFree</objectAutonumerationMode>
<modalityUseMode>DontUse</modalityUseMode>
<synchronousPlatformExtensionAndAddInCallUseMode>DontUse</synchronousPlatformExtensionAndAddInCallUseMode>
<compatibilityMode>8.3.19</compatibilityMode>
<languages uuid="6cdbd6a6-698d-4e00-9529-7f98c48cfe04">
<name>Русский</name>
<synonym>
<key>ru</key>
<value>Русский</value>
</synonym>
<languageCode>ru</languageCode>
</languages>
<commonModules>CommonModule.ОбщийМодуль1</commonModules>
</mdclass:Configuration>