Skip to content

Commit 92ec8dd

Browse files
authored
Merge pull request #1880 from artbear/WriteLogEvent-1714
[FN] UsageWriteLogEvent - сейчас не срабатывает, если в блоке исключения есть получение краткого представления ошибки, но нет полного
2 parents b2cb41a + fcf6cb3 commit 92ec8dd

File tree

3 files changed

+194
-52
lines changed

3 files changed

+194
-52
lines changed

src/main/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsageWriteLogEventDiagnostic.java

Lines changed: 72 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
import javax.annotation.Nullable;
3535
import java.util.Collection;
36+
import java.util.List;
3637
import java.util.Objects;
3738
import java.util.Optional;
3839
import java.util.regex.Pattern;
@@ -54,10 +55,13 @@ public class UsageWriteLogEventDiagnostic extends AbstractVisitorDiagnostic {
5455
private static final Pattern PATTERN_DETAIL_ERROR_DESCRIPTION = CaseInsensitivePattern.compile(
5556
"подробноепредставлениеошибки|detailerrordescription"
5657
);
58+
private static final Pattern PATTERN_BRIEF_ERROR_DESCRIPTION = CaseInsensitivePattern.compile(
59+
"краткоепредставлениеошибки|brieferrordescription"
60+
);
5761
private static final Pattern PATTERN_ERROR_INFO = CaseInsensitivePattern.compile(
5862
"информацияобошибке|errorinfo"
5963
);
60-
private static final Pattern PATTERN_BRIEF_ERROR_DESCRIPTION = CaseInsensitivePattern.compile(
64+
private static final Pattern PATTERN_SIMPLE_ERROR_DESCRIPTION = CaseInsensitivePattern.compile(
6165
"описаниеошибки|errordescription"
6266
);
6367
private static final Pattern PATTERN_EVENT_LOG_LEVEL = CaseInsensitivePattern.compile(
@@ -68,58 +72,73 @@ public class UsageWriteLogEventDiagnostic extends AbstractVisitorDiagnostic {
6872
);
6973

7074
private static final int WRITE_LOG_EVENT_METHOD_PARAMS_COUNT = 5;
75+
public static final int COMMENTS_PARAM_INDEX = 4;
76+
public static final String NO_ERROR_LOG_LEVEL_INSIDE_EXCEPT_BLOCK = "noErrorLogLevelInsideExceptBlock";
77+
public static final String NO_DETAIL_ERROR_DESCRIPTION = "noDetailErrorDescription";
7178
public static final String WRONG_NUMBER_MESSAGE = "wrongNumberMessage";
7279
public static final String NO_SECOND_PARAMETER = "noSecondParameter";
7380
public static final String NO_COMMENT = "noComment";
74-
public static final String NO_ERROR_LOG_LEVEL_INSIDE_EXCEPT_BLOCK = "noErrorLogLevelInsideExceptBlock";
75-
public static final String NO_DETAIL_ERROR_DESCRIPTION = "noDetailErrorDescription";
7681

7782
@Override
78-
public ParseTree visitGlobalMethodCall(BSLParser.GlobalMethodCallContext ctx) {
83+
public ParseTree visitGlobalMethodCall(BSLParser.GlobalMethodCallContext context) {
7984

80-
if (!checkMethodName(ctx)) {
81-
return super.defaultResult();
85+
if (!checkMethodName(context)) {
86+
return super.visitGlobalMethodCall(context);
8287
}
8388

84-
final var callParams = ctx.doCall().callParamList().callParam();
85-
if (callParams.size() < WRITE_LOG_EVENT_METHOD_PARAMS_COUNT) {
86-
fireIssue(ctx, WRONG_NUMBER_MESSAGE);
87-
return super.defaultResult();
88-
}
89+
checkParams(context);
8990

90-
final BSLParser.CallParamContext secondParamCtx = callParams.get(1);
91-
if (secondParamCtx.getChildCount() == 0) {
92-
fireIssue(ctx, NO_SECOND_PARAMETER);
93-
return super.defaultResult();
94-
}
91+
return super.defaultResult();
92+
}
9593

96-
final BSLParser.CallParamContext commentCtx = callParams.get(4);
97-
if (commentCtx.getChildCount() == 0) {
98-
fireIssue(ctx, NO_COMMENT);
99-
return super.defaultResult();
94+
private void checkParams(BSLParser.GlobalMethodCallContext context) {
95+
final var callParams = context.doCall().callParamList().callParam();
96+
if (!checkFirstParams(context, callParams)){
97+
return;
10098
}
10199

102-
if (isInsideExceptBlock(ctx)){
103-
if (!hasErrorLogLevel(secondParamCtx)) {
104-
fireIssue(ctx, NO_ERROR_LOG_LEVEL_INSIDE_EXCEPT_BLOCK);
105-
return super.defaultResult();
100+
if (isInsideExceptBlock(context)) {
101+
102+
final var logLevelCtx = callParams.get(1);
103+
if (!hasErrorLogLevel(logLevelCtx)) {
104+
fireIssue(context, NO_ERROR_LOG_LEVEL_INSIDE_EXCEPT_BLOCK);
105+
return;
106106
}
107107

108+
final var commentCtx = callParams.get(COMMENTS_PARAM_INDEX);
108109
if (!isCommentCorrect(commentCtx)) {
109-
fireIssue(ctx, NO_DETAIL_ERROR_DESCRIPTION);
110+
fireIssue(context, NO_DETAIL_ERROR_DESCRIPTION);
110111
}
111112
}
113+
}
112114

113-
return super.defaultResult();
115+
private boolean checkFirstParams(BSLParser.GlobalMethodCallContext context, List<? extends BSLParser.CallParamContext> callParams) {
116+
if (callParams.size() < WRITE_LOG_EVENT_METHOD_PARAMS_COUNT) {
117+
fireIssue(context, WRONG_NUMBER_MESSAGE);
118+
return false;
119+
}
120+
121+
final BSLParser.CallParamContext secondParamCtx = callParams.get(1);
122+
if (secondParamCtx.getChildCount() == 0) {
123+
fireIssue(context, NO_SECOND_PARAMETER);
124+
return false;
125+
}
126+
127+
final BSLParser.CallParamContext commentCtx = callParams.get(COMMENTS_PARAM_INDEX);
128+
if (commentCtx.getChildCount() == 0) {
129+
fireIssue(context, NO_COMMENT);
130+
return false;
131+
}
132+
return true;
114133
}
115134

116-
private static boolean checkMethodName(BSLParser.GlobalMethodCallContext ctx) {
117-
return WRITELOGEVENT.matcher(ctx.methodName().getText()).matches();
135+
private static boolean checkMethodName(BSLParser.GlobalMethodCallContext context) {
136+
return WRITELOGEVENT.matcher(context.methodName().getText()).matches();
118137
}
119138

120-
private void fireIssue(BSLParser.GlobalMethodCallContext ctx, String messageKey) {
139+
private void fireIssue(BSLParser.GlobalMethodCallContext context, String messageKey) {
121140
var diagnosticMessage = info.getResourceString(messageKey);
122-
diagnosticStorage.addDiagnostic(ctx, diagnosticMessage);
141+
diagnosticStorage.addDiagnostic(context, diagnosticMessage);
123142
}
124143

125144
private static boolean hasErrorLogLevel(BSLParser.CallParamContext callParamContext) {
@@ -186,7 +205,7 @@ private static boolean isValidExpression(
186205
if (isErrorDescriptionCallCorrect(assignmentGlobalCalls)) {
187206
return true;
188207
}
189-
if (hasBriefErrorDescription(assignmentGlobalCalls)) {
208+
if (hasSimpleErrorDescription(assignmentGlobalCalls) || hasBriefErrorDescription(assignmentGlobalCalls)) {
190209
return false;
191210
}
192211
}
@@ -195,44 +214,50 @@ private static boolean isValidExpression(
195214

196215
private static boolean isErrorDescriptionCallCorrect(Collection<ParseTree> globalCalls) {
197216
return globalCalls.stream()
198-
.filter(ctx -> ctx instanceof BSLParser.GlobalMethodCallContext)
217+
.filter(context -> context instanceof BSLParser.GlobalMethodCallContext)
199218
.map(BSLParser.GlobalMethodCallContext.class::cast)
200-
.filter(ctx -> isAppropriateName(ctx, PATTERN_DETAIL_ERROR_DESCRIPTION))
219+
.filter(context -> isAppropriateName(context, PATTERN_DETAIL_ERROR_DESCRIPTION))
201220
.anyMatch(UsageWriteLogEventDiagnostic::hasFirstDescendantGlobalCall);
202221
}
203222

204223
private static boolean isAppropriateName(
205-
BSLParser.GlobalMethodCallContext ctx,
224+
BSLParser.GlobalMethodCallContext context,
206225
Pattern patternDetailErrorDescription
207226
) {
208-
return patternDetailErrorDescription.matcher(ctx.methodName().getText()).matches();
227+
return patternDetailErrorDescription.matcher(context.methodName().getText()).matches();
209228
}
210229

211230
private static boolean hasFirstDescendantGlobalCall(BSLParser.GlobalMethodCallContext globalCallCtx) {
212231
return Trees.findAllRuleNodes(globalCallCtx, BSLParser.RULE_globalMethodCall).stream()
213232
.map(BSLParser.GlobalMethodCallContext.class::cast)
214-
.anyMatch(ctx -> isAppropriateName(ctx, PATTERN_ERROR_INFO));
233+
.anyMatch(context -> isAppropriateName(context, PATTERN_ERROR_INFO));
234+
}
235+
236+
private static boolean hasSimpleErrorDescription(Collection<ParseTree> globalCalls) {
237+
return globalCalls.stream()
238+
.filter(context -> context instanceof BSLParser.GlobalMethodCallContext)
239+
.anyMatch(context -> isAppropriateName((BSLParser.GlobalMethodCallContext) context, PATTERN_SIMPLE_ERROR_DESCRIPTION));
215240
}
216241

217242
private static boolean hasBriefErrorDescription(Collection<ParseTree> globalCalls) {
218243
return globalCalls.stream()
219-
.filter(ctx -> ctx instanceof BSLParser.GlobalMethodCallContext)
220-
.anyMatch(ctx -> isAppropriateName((BSLParser.GlobalMethodCallContext) ctx, PATTERN_BRIEF_ERROR_DESCRIPTION));
244+
.filter(context -> context instanceof BSLParser.GlobalMethodCallContext)
245+
.anyMatch(context -> isAppropriateName((BSLParser.GlobalMethodCallContext) context, PATTERN_BRIEF_ERROR_DESCRIPTION));
221246
}
222247

223-
private static boolean isValidExpression(BSLParser.ExpressionContext ctx, BSLParser.CodeBlockContext codeBlock,
248+
private static boolean isValidExpression(BSLParser.ExpressionContext context, BSLParser.CodeBlockContext codeBlock,
224249
boolean checkPrevAssignment) {
225-
return ctx.member().stream()
250+
return context.member().stream()
226251
.allMatch(memberContext -> isValidExpression(memberContext, codeBlock, checkPrevAssignment));
227252
}
228253

229-
private static boolean isValidExpression(BSLParser.MemberContext ctx, BSLParser.CodeBlockContext codeBlock,
254+
private static boolean isValidExpression(BSLParser.MemberContext context, BSLParser.CodeBlockContext codeBlock,
230255
boolean checkPrevAssignment) {
231-
if (ctx.constValue() != null) {
256+
if (context.constValue() != null) {
232257
return false;
233258
}
234259
if (checkPrevAssignment) {
235-
final var complexIdentifier = ctx.complexIdentifier();
260+
final var complexIdentifier = context.complexIdentifier();
236261
if (complexIdentifier != null) {
237262
return isValidVarAssignment(complexIdentifier, codeBlock);
238263
}
@@ -241,10 +266,10 @@ private static boolean isValidExpression(BSLParser.MemberContext ctx, BSLParser.
241266
}
242267

243268
private static boolean isValidVarAssignment(
244-
BSLParser.ComplexIdentifierContext varContext,
269+
BSLParser.ComplexIdentifierContext identifierContext,
245270
BSLParser.CodeBlockContext codeBlock
246271
) {
247-
String varName = varContext.getText();
272+
String varName = identifierContext.getText();
248273
return getAssignment(varName, codeBlock)
249274
.map(BSLParser.AssignmentContext::expression)
250275
.map(expression -> isValidExpression(codeBlock, expression, false))
@@ -263,8 +288,8 @@ private static Optional<BSLParser.AssignmentContext> getAssignment(
263288
.filter(assignmentContext -> assignmentContext.lValue().getText().equalsIgnoreCase(varName));
264289
}
265290

266-
private static boolean isInsideExceptBlock(BSLParserRuleContext ctx) {
267-
return Trees.getRootParent(ctx, BSLParser.RULE_exceptCodeBlock) != null;
291+
private static boolean isInsideExceptBlock(BSLParserRuleContext context) {
292+
return Trees.getRootParent(context, BSLParser.RULE_exceptCodeBlock) != null;
268293
}
269294

270295
}

src/test/java/com/github/_1c_syntax/bsl/languageserver/diagnostics/UsageWriteLogEventDiagnosticTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,16 @@ void test() {
4646
.hasRange(11, 4, 79)
4747
.hasRange(16, 6, 17, 25)
4848
.hasRange(23, 6, 24, 24)
49-
.hasRange(31, 6, 32, 35)
49+
.hasRange(31, 6, 32, 45)
5050
.hasRange(38, 6, 39, 37)
5151
.hasRange(45, 6, 46, 21)
52+
.hasRange(45, 6, 46, 21)
53+
.hasRange(190, 6, 192,56)
54+
.hasRange(204, 6, 206,22)
55+
.hasRange(219, 6, 221,22)
56+
.hasRange(286, 12, 291,39)
57+
.hasSize(14)
5258
;
53-
assertThat(diagnostics).hasSize(10);
5459

5560
}
5661
}

src/test/resources/diagnostics/UsageWriteLogEventDiagnostic.bsl

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
Попытка
2929
ПравильноеИсключениеВКодеСервер();
3030
Исключение
31-
ТекстОшибки = "Описание";
31+
ТекстОшибки = "Описание" + Метод();
3232
ЗаписьЖурналаРегистрации("Событие", УровеньЖурналаРегистрации.Ошибка, , ,
33-
"Еще текст " + ТекстОшибки); // ошибка
33+
"Еще текст " + ТекстОшибки + Метод()); // ошибка
3434
КонецПопытки;
3535

3636
Попытка
@@ -164,7 +164,7 @@
164164
Процедура ПравильноЗаписатьОшибкуРаботыСФайлами(Знач ПодробноеПредставлениеОшибки)
165165
ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
166166
УровеньЖурналаРегистрации.Ошибка,,,
167-
ПодробноеПредставлениеОшибки);
167+
ПодробноеПредставлениеОшибки); // не ошибка
168168
КонецПроцедуры
169169

170170
&НаСервере
@@ -180,3 +180,115 @@
180180
ТекстОшибки);
181181
КонецПопытки;
182182
КонецПроцедуры
183+
184+
&НаКлиенте
185+
Процедура ВИсключенииЕстьКраткоеПредставлениеНоНетПолного()
186+
Попытка
187+
// клиентский код, приводящий к вызову исключения
188+
СоздатьФайлНаДиске();
189+
Исключение
190+
ПоказатьПредупреждение(,НСтр("ru = 'Операция не может быть выполнена по причине:'") + Символы.ПС + ТекстСообщения);
191+
ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
192+
УровеньЖурналаРегистрации.Ошибка,,,
193+
КраткоеПредставлениеОшибки(ИнформацияОбОшибке())); // ошибка
194+
КонецПопытки;
195+
КонецПроцедуры
196+
197+
&НаКлиенте
198+
Процедура ВИсключенииЕстьКраткоеПредставлениеНоНетПолного1()
199+
Попытка
200+
// клиентский код, приводящий к вызову исключения
201+
СоздатьФайлНаДиске();
202+
Исключение
203+
ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
204+
ПоказатьПредупреждение(,НСтр("ru = 'Операция не может быть выполнена по причине:'") + Символы.ПС + ТекстСообщения);
205+
ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
206+
УровеньЖурналаРегистрации.Ошибка,,,
207+
ТекстСообщения); // ошибка
208+
КонецПопытки;
209+
КонецПроцедуры
210+
211+
&НаКлиенте
212+
Процедура ВИсключенииЕстьКраткоеПредставлениеНоНетПолного2()
213+
Попытка
214+
// клиентский код, приводящий к вызову исключения
215+
СоздатьФайлНаДиске();
216+
Исключение
217+
ТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
218+
ДругойТекстСообщения = ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
219+
ПоказатьПредупреждение(,НСтр("ru = 'Операция не может быть выполнена по причине:'") + Символы.ПС + ТекстСообщения);
220+
ЗаписьЖурналаРегистрации(НСтр("ru = 'Выполнение операции'"),
221+
УровеньЖурналаРегистрации.Ошибка,,,
222+
ТекстСообщения); // ошибка
223+
КонецПопытки;
224+
КонецПроцедуры
225+
226+
Процедура ОбычнаяЗаписьВЖР(Знач ИмяСобытия, Знач ОписаниеОшибки, Знач Ответ, Знач СсылкаНаДанные = Неопределено) Экспорт
227+
ТекстЗаписи = ТекстОтвета(ОписаниеОшибки, Ответ);
228+
229+
ЗаписьЖурналаРегистрации(
230+
ИмяСобытия,
231+
УровеньЖурналаРегистрации.Ошибка,
232+
,
233+
СсылкаНаДанные,
234+
ТекстЗаписи); // не ошибка
235+
КонецПроцедуры
236+
237+
Процедура СложныйМетодСИспользованиемПодробногоПредставленияВнутриИсключения(Знач ИмяСобытия, Знач ОписаниеОшибки, Знач Ответ, Знач СсылкаНаДанные = Неопределено) Экспорт
238+
Попытка
239+
Блокировка.Заблокировать();
240+
Исключение
241+
ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
242+
НСтр("ru = 'Не удалось обработать график работы по причине:
243+
|%2'"),
244+
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
245+
246+
ЗаписьЖурналаРегистрации(
247+
ИмяСобытия,
248+
УровеньЖурналаРегистрации.Ошибка,
249+
,
250+
СсылкаНаДанные,
251+
ТекстСообщения); // не ошибка
252+
КонецПопытки;
253+
КонецПроцедуры
254+
255+
Процедура СложныйМетодСИспользованиемПодробногоПредставленияВнутриИсключенияВВыражении(Знач Выборка, Знач Блокировка) Экспорт
256+
Попытка
257+
Блокировка.Заблокировать();
258+
Исключение
259+
ТекстСообщения =
260+
НСтр("ru = 'Не удалось установить разделение сеанса. Область данных'") + " = "
261+
+ Формат(Выборка.ОбластьДанных, "ЧГ=0")
262+
+ Символы.ПС + ПодробноеПредставлениеОшибки(ИнформацияОбОшибке());
263+
264+
ЗаписьЖурналаРегистрации(
265+
ИмяСобытия,
266+
УровеньЖурналаРегистрации.Ошибка,
267+
,
268+
СсылкаНаДанные,
269+
ТекстСообщения); // не ошибка
270+
271+
ЗаписьЖурналаРегистрации(
272+
ИмяСобытия,
273+
УровеньОшибки(),
274+
,
275+
СсылкаНаДанные,
276+
ТекстСообщения); // не ошибка
277+
278+
КонецПопытки;
279+
КонецПроцедуры
280+
281+
Процедура Метод2(Знач СсылкаНаДанные, Знач Блокировка)
282+
Попытка
283+
Блокировка.Заблокировать();
284+
Исключение
285+
КороткийТекстСообщения = КраткоеПредставлениеОшибки(ИнформацияОбОшибке()) + ОписаниеОшибки();
286+
287+
ЗаписьЖурналаРегистрации(
288+
ИмяСобытия,
289+
УровеньЖурналаРегистрации.Ошибка,
290+
,
291+
СсылкаНаДанные,
292+
КороткийТекстСообщения); // ошибка
293+
КонецПопытки;
294+
КонецПроцедуры

0 commit comments

Comments
 (0)