1
0
mirror of https://github.com/1C-Company/v8-code-style.git synced 2025-02-14 16:59:56 +02:00

Между "НачатьТранзакцию()" и "Попытка" есть исполняемый код (#1063)

This commit is contained in:
Artem Iliukhin 2022-07-13 18:20:52 +03:00 committed by GitHub
parent a48f5b8b68
commit ee64a061e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 275 additions and 2 deletions

View File

@ -37,6 +37,9 @@
2. Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ОтменитьТранзакцию()" 2. Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ОтменитьТранзакцию()"
3. Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ЗафиксироватьТранзакцию()" 3. Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ЗафиксироватьТранзакцию()"
4. Mежду "Исключение" и "ОтменитьТранзакцию()" есть исполняемый код, который может вызвать исключение 4. Mежду "Исключение" и "ОтменитьТранзакцию()" есть исполняемый код, который может вызвать исключение
- Проверка нарушения схемы работы с транзакциями связанной с началом транзакции:
1. Mежду "НачатьТранзакцию()" и "Попытка" есть исполняемый код, который может вызвать исключение
2. Не найден оператор "Попытка" после вызова "НачатьТранзакцию()"
- Отсутствует удаление временного файла после использования. - Отсутствует удаление временного файла после использования.
#### Запросы #### Запросы

View File

@ -0,0 +1,31 @@
# There is no Try-Exception block after the start of the transaction
There should be no executable code between begin transaction and try,
the try operator was not found after calling begin transaction
## Noncompliant Code Example
```bsl
BeginTransaction();
CommitTransaction();
```
## Compliant Solution
```bsl
BeginTransaction();
Try
// ...
CommitTransaction();
Except
// ...
RollbackTransaction();
// ...
Raise;
EndTry;
```
## See
- [Catching exceptions in code](https://support.1ci.com/hc/en-us/articles/360011002440-Catching-exceptions-in-code)
- [Transactions: rules of use](https://support.1ci.com/hc/en-us/articles/360011121239-Transactions-rules-of-use)

View File

@ -0,0 +1,31 @@
# После начала транзакции отсуствует блок Попытка-Исключение
Mежду "НачатьТранзакцию()" и "Попытка" есть исполняемый код, который может вызвать исключение,
после "НачатьТранзакцию()" не найден оператор "Попытка"
## Неправильно
```bsl
НачатьТранзакцию();
ЗафиксироватьТранзакцию();
```
## Правильно
```bsl
НачатьТранзакцию();
Попытка
// ...
ЗафиксироватьТранзакцию();
Исключение
// ...
ОтменитьТранзакцию();
// ...
ВызватьИсключение;
КонецПопытки;
```
## См.
- [Перехват исключений в коде](https://its.1c.ru/db/v8std#content:499:hdoc:3.6)
- [Транзакции: правила использования](https://its.1c.ru/db/v8std#content:783:hdoc:1.3)

View File

@ -267,6 +267,10 @@
category="com.e1c.v8codestyle.bsl" category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.bsl.check.RollbackTransactionCheck"> class="com.e1c.v8codestyle.bsl.check.RollbackTransactionCheck">
</check> </check>
<check
category="com.e1c.v8codestyle.bsl"
class="com.e1c.v8codestyle.bsl.check.BeginTransactionCheck">
</check>
</extension> </extension>
<extension <extension
point="org.eclipse.core.runtime.preferences"> point="org.eclipse.core.runtime.preferences">

View File

@ -0,0 +1,96 @@
/*******************************************************************************
* Copyright (C) 2022, 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:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check;
import static com._1c.g5.v8.dt.bsl.model.BslPackage.Literals.INVOCATION;
import org.eclipse.core.runtime.IProgressMonitor;
import com._1c.g5.v8.dt.bsl.model.FeatureAccess;
import com._1c.g5.v8.dt.bsl.model.Invocation;
import com._1c.g5.v8.dt.bsl.model.Statement;
import com._1c.g5.v8.dt.bsl.model.StaticFeatureAccess;
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.settings.IssueSeverity;
import com.e1c.g5.v8.dt.check.settings.IssueType;
/**
* The try operator was not found after calling begin transaction,
* there should be no executable code between begin transaction and try,
*
* @author Artem Iliukhin
*/
public final class BeginTransactionCheck
extends AbstractTransactionCheck
{
private static final String CHECK_ID = "begin-transaction"; //$NON-NLS-1$
@Override
public String getCheckId()
{
return CHECK_ID;
}
@Override
protected void configureCheck(CheckConfigurer builder)
{
builder.title(Messages.BeginTransactionCheck_Begin_transaction_is_incorrect)
.description(Messages.BeginTransactionCheck_Try_must_be_after_begin)
.complexity(CheckComplexity.NORMAL)
.severity(IssueSeverity.MINOR)
.issueType(IssueType.WARNING)
.disable()
.module()
.checkedObjectType(INVOCATION);
}
@Override
protected void check(Object object, ResultAcceptor resultAceptor, ICheckParameters parameters,
IProgressMonitor monitor)
{
Invocation inv = (Invocation)object;
FeatureAccess featureAccess = inv.getMethodAccess();
if (featureAccess instanceof StaticFeatureAccess)
{
if (monitor.isCanceled())
{
return;
}
String nameFeature = featureAccess.getName();
if (!(BEGIN_TRANSACTION_RU.equalsIgnoreCase(nameFeature)
|| BEGIN_TRANSACTION.equalsIgnoreCase(nameFeature)))
{
return;
}
Statement statement = getStatementFromInvoc(inv);
if (statement != null)
{
statement = getNextStatement(statement);
if (statement == null)
{
resultAceptor.addIssue(Messages.BeginTransactionCheck_Try_was_not_found_after_calling_begin, inv);
}
else if (!(statement instanceof TryExceptStatement))
{
resultAceptor.addIssue(
Messages.BeginTransactionCheck_Executable_code_between_begin_transaction_and_try, inv);
}
}
}
}
}

View File

@ -60,12 +60,20 @@ final class Messages
public static String RollbackTransactionCheck_Should_be_no_executable_code_between_exception_and_rollback; public static String RollbackTransactionCheck_Should_be_no_executable_code_between_exception_and_rollback;
public static String BeginTransactionCheck_Executable_code_between_begin_transaction_and_try;
public static String CommitTransactionCheck_Transaction_contains_empty_except; public static String CommitTransactionCheck_Transaction_contains_empty_except;
public static String CommitTransactionCheck_Transactions_is_broken; public static String CommitTransactionCheck_Transactions_is_broken;
public static String CommitTransactionCheck_Transactions_is_broken_des; public static String CommitTransactionCheck_Transactions_is_broken_des;
public static String BeginTransactionCheck_Begin_transaction_is_incorrect;
public static String BeginTransactionCheck_Try_must_be_after_begin;
public static String BeginTransactionCheck_Try_was_not_found_after_calling_begin;
public static String CommonModuleNamedSelfReferenceCheck_description; public static String CommonModuleNamedSelfReferenceCheck_description;
public static String CommonModuleNamedSelfReferenceCheck_issue; public static String CommonModuleNamedSelfReferenceCheck_issue;

View File

@ -54,12 +54,20 @@ CommitTransactionCheck_Should_be_no_executable_code_between_commit_and_exception
RollbackTransactionCheck_Should_be_no_executable_code_between_exception_and_rollback=There should be no executable code between exception and rollback transaction RollbackTransactionCheck_Should_be_no_executable_code_between_exception_and_rollback=There should be no executable code between exception and rollback transaction
BeginTransactionCheck_Executable_code_between_begin_transaction_and_try=There should be no executable code between begin transaction and try
CommitTransactionCheck_Transaction_contains_empty_except=The transaction contains an empty exception block CommitTransactionCheck_Transaction_contains_empty_except=The transaction contains an empty exception block
CommitTransactionCheck_Transactions_is_broken=Commit transaction is incorrect CommitTransactionCheck_Transactions_is_broken=Commit transaction is incorrect
CommitTransactionCheck_Transactions_is_broken_des=Commit transaction must be in a try-catch, there should be no executable code between commit transaction and exception, there is no begin transaction for commit transaction, there is no rollback transaction for begin transaction. CommitTransactionCheck_Transactions_is_broken_des=Commit transaction must be in a try-catch, there should be no executable code between commit transaction and exception, there is no begin transaction for commit transaction, there is no rollback transaction for begin transaction.
BeginTransactionCheck_Begin_transaction_is_incorrect=Begin transaction is incorrect
BeginTransactionCheck_Try_must_be_after_begin=Try-catch must be after begin transaction
BeginTransactionCheck_Try_was_not_found_after_calling_begin=The try operator was not found after calling begin transaction
CommonModuleNamedSelfReferenceCheck_description=Excessive named self reference CommonModuleNamedSelfReferenceCheck_description=Excessive named self reference
CommonModuleNamedSelfReferenceCheck_issue=Excessive named self reference CommonModuleNamedSelfReferenceCheck_issue=Excessive named self reference

View File

@ -46,14 +46,20 @@ CommitTransactionCheck_No_begin_transaction_for_commit_transaction=Отсутс
CommitTransactionCheck_No_begin_transaction_for_rollback_transaction=Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ОтменитьТранзакцию()" CommitTransactionCheck_No_begin_transaction_for_rollback_transaction=Отсутствует вызов "НачатьТранзакцию()", хотя вызываются "ОтменитьТранзакцию()"
CommitTransactionCheck_No_commit_transaction_for_begin_transaction=Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ЗафиксироватьТранзакцию()"
CommitTransactionCheck_No_rollback_transaction_for_begin_transaction=Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ОтменитьТранзакцию()" CommitTransactionCheck_No_rollback_transaction_for_begin_transaction=Для вызова "НачатьТранзакцию()" отсутствует парный вызов "ОтменитьТранзакцию()"
CommitTransactionCheck_Should_be_no_executable_code_between_commit_and_exception=Mежду "ЗафиксироватьТранзакцию()" и "Исключение" есть исполняемый код, который может вызвать исключение CommitTransactionCheck_Should_be_no_executable_code_between_commit_and_exception=Mежду "ЗафиксироватьТранзакцию()" и "Исключение" есть исполняемый код, который может вызвать исключение
CommitTransactionCheck_Should_be_no_executable_code_between_exception_and_rollback=Mежду "Исключение" и "ОтменитьТранзакцию()" есть исполняемый код, который может вызвать исключение CommitTransactionCheck_Should_be_no_executable_code_between_exception_and_rollback=Mежду "Исключение" и "ОтменитьТранзакцию()" есть исполняемый код, который может вызвать исключение
BeginTransactionCheck_Executable_code_between_begin_transaction_and_try=Между "НачатьТранзакцию()" и "Попытка" есть исполняемый код
BeginTransactionCheck_Try_was_not_found_after_calling_begin=Не найден оператор "Попытка" после вызова "НачатьТранзакцию()"
BeginTransactionCheck_Begin_transaction_is_incorrect=Нарушена схема работы с "НачатьТранзакцию()"
BeginTransactionCheck_Try_must_be_after_begin=После начала транзакции не найден оператор "Попытка"
CommitTransactionCheck_Transaction_contains_empty_except=Транзакция содержит пустой блок Исключение CommitTransactionCheck_Transaction_contains_empty_except=Транзакция содержит пустой блок Исключение
CommitTransactionCheck_Transactions_is_broken=Нарушена схема работы с "ЗафиксироватьТранзакцию()" CommitTransactionCheck_Transactions_is_broken=Нарушена схема работы с "ЗафиксироватьТранзакцию()"

View File

@ -0,0 +1,5 @@
Процедура Тест()
НачатьТранзакцию();
КонецПроцедуры

View File

@ -0,0 +1,17 @@
Процедура Тест()
НачатьТранзакцию();
Тест = 1;
Попытка
// 2. Вся логика блокировки и обработки данных размещается в блоке Попытка-Исключение
// 3. В самом конце обработки данных выполняется попытка зафиксировать транзакцию
ЗафиксироватьТранзакцию();
Исключение
// 4. В случае любых проблем с СУБД, транзакция сначала отменяется...
ОтменитьТранзакцию();
// 5. ...затем проблема фиксируется в журнале регистрации...
// 6. ... после чего, проблема передается дальше вызывающему коду.
ВызватьИсключение;
КонецПопытки;
КонецПроцедуры

View File

@ -0,0 +1,63 @@
/*******************************************************************************
* Copyright (C) 2022, 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:
* 1C-Soft LLC - initial API and implementation
*******************************************************************************/
package com.e1c.v8codestyle.bsl.check.itests;
import static org.junit.Assert.assertEquals;
import java.util.List;
import org.junit.Test;
import com._1c.g5.v8.dt.validation.marker.Marker;
import com.e1c.v8codestyle.bsl.check.BeginTransactionCheck;
/**
* Tests for {@link BeginTransactionCheck} check.
*
* @author Artem Iliukhin
*/
public class BeginTransactionCheckTest
extends AbstractSingleModuleTestBase
{
/**
* Instantiates a new commit transaction check test.
*/
public BeginTransactionCheckTest()
{
super(BeginTransactionCheck.class);
}
@Test
public void testNotFoundTryAfterBegin() throws Exception
{
updateModule(FOLDER_RESOURCE + "not-found-try-after-begin.bsl");
List<Marker> markers = getModuleMarkers();
assertEquals(1, markers.size());
Marker marker = markers.get(0);
assertEquals("The try operator was not found after calling begin transaction", marker.getMessage());
}
@Test
public void testShouldBeNoExecutableCodebetweenBeginAndTry() throws Exception
{
updateModule(FOLDER_RESOURCE + "should-be-no-executable-code-between-begin-and-try.bsl");
List<Marker> markers = getModuleMarkers();
assertEquals(1, markers.size());
Marker marker = markers.get(0);
assertEquals("There should be no executable code between begin transaction and try", marker.getMessage());
}
}

View File

@ -82,4 +82,5 @@ public class CommitTransactionCheckTest
assertEquals("There should be no executable code between commit transaction and exception", assertEquals("There should be no executable code between commit transaction and exception",
marker.getMessage()); marker.getMessage());
} }
} }