diff --git a/src/ScriptEngine/Machine/Contexts/ExceptionInfoContext.cs b/src/ScriptEngine/Machine/Contexts/ExceptionInfoContext.cs index 869d6d408..30c9588df 100644 --- a/src/ScriptEngine/Machine/Contexts/ExceptionInfoContext.cs +++ b/src/ScriptEngine/Machine/Contexts/ExceptionInfoContext.cs @@ -33,10 +33,11 @@ public ExceptionInfoContext(ScriptException source) : base(ObjectType) SetActualException(source); } - private ExceptionInfoContext(string message, IValue parameters) : base(ObjectType) + private ExceptionInfoContext(string message, IValue parameters, ExceptionInfoContext cause) : base(ObjectType) { Description = message; Parameters = parameters; + _innerException = cause; } public bool IsErrorTemplate => _exc == null; @@ -48,10 +49,11 @@ private void SetActualException(ScriptException exception) if (exception is ParametrizedRuntimeException pre) { Parameters = pre.Parameter; + _innerException = pre.Cause; } } - private ScriptException ActualException() + public ScriptException ActualException() { if (IsErrorTemplate) { @@ -147,8 +149,8 @@ public IValue InnerException private IValue CreateInnerExceptionInfo() { - var exc = ActualException(); - if (exc.InnerException == null) + var exc = _exc; + if (exc?.InnerException == null) return ValueFactory.Create(); var alreadyWrapped = ActualException() is ExternalSystemException; @@ -193,11 +195,17 @@ public override string ToString() return Description; } - + /// + /// + /// + /// Строка - Сообщение об ошибке + /// Произвольный - Дополнительная информация + /// ИнформацияОбОшибке - Причина, по которой произошло текущее исключение + /// [ScriptConstructor(Name = "С возможностью передачи параметров")] - public static ExceptionInfoContext Create(IValue msg, IValue parameter) + public static ExceptionInfoContext Create(IValue msg, IValue parameter, ExceptionInfoContext cause = null) { - return new ExceptionInfoContext(msg.AsString(), parameter); + return new ExceptionInfoContext(msg.AsString(), parameter, cause); } public static ExceptionInfoContext EmptyExceptionInfo() diff --git a/src/ScriptEngine/Machine/ExceptionInfoFactory.cs b/src/ScriptEngine/Machine/ExceptionInfoFactory.cs index 1afa05c39..51e8172bf 100644 --- a/src/ScriptEngine/Machine/ExceptionInfoFactory.cs +++ b/src/ScriptEngine/Machine/ExceptionInfoFactory.cs @@ -48,7 +48,7 @@ public Exception Raise(object raiseValue) return raiseValue switch { ExceptionInfoContext { IsErrorTemplate: true } excInfo => - new ParametrizedRuntimeException(excInfo.Description, excInfo.Parameters), + new ParametrizedRuntimeException(excInfo.Description, excInfo.Parameters, excInfo.InnerException), BslValue bslVal => new RuntimeException(bslVal.AsString()), _ => new RuntimeException(raiseValue.ToString()) }; diff --git a/src/ScriptEngine/Machine/MachineInstance.cs b/src/ScriptEngine/Machine/MachineInstance.cs index e342cf4aa..7f64884e9 100644 --- a/src/ScriptEngine/Machine/MachineInstance.cs +++ b/src/ScriptEngine/Machine/MachineInstance.cs @@ -1252,7 +1252,11 @@ private void RaiseException(int arg) var exceptionValue = _operationStack.Pop().GetRawValue(); if (exceptionValue is ExceptionInfoContext { IsErrorTemplate: true } excInfo) { - throw new ParametrizedRuntimeException(excInfo.Description, excInfo.Parameters); + throw new ParametrizedRuntimeException( + excInfo.Description, + excInfo.Parameters, + excInfo.InnerException + ); } else { diff --git a/src/ScriptEngine/Machine/ParametrizedRuntimeException.cs b/src/ScriptEngine/Machine/ParametrizedRuntimeException.cs index 22f5e4e0b..097681de6 100644 --- a/src/ScriptEngine/Machine/ParametrizedRuntimeException.cs +++ b/src/ScriptEngine/Machine/ParametrizedRuntimeException.cs @@ -6,16 +6,19 @@ This Source Code Form is subject to the terms of the ----------------------------------------------------------*/ using OneScript.Exceptions; +using ScriptEngine.Machine.Contexts; namespace ScriptEngine.Machine { public class ParametrizedRuntimeException : RuntimeException { - public ParametrizedRuntimeException(string msg, IValue parameter) : base(msg) + public ParametrizedRuntimeException(string msg, IValue parameter, IValue cause = null) : base(msg) { Parameter = parameter; + Cause = cause; } public IValue Parameter { get; private set; } + public IValue Cause { get; private set; } } } diff --git a/tests/global-funcs.os b/tests/global-funcs.os index 50d9d4d37..a83cd129c 100644 --- a/tests/global-funcs.os +++ b/tests/global-funcs.os @@ -77,6 +77,7 @@ ВсеТесты.Добавить("Тест_ДолженПроверитьИнформацияОбОшибкеОписание"); ВсеТесты.Добавить("Тест_ДолженПроверитьКраткоеПредставлениеОшибки"); ВсеТесты.Добавить("Тест_ДолженПроверитьПодробноеПредставлениеОшибки"); + ВсеТесты.Добавить("Тест_ДолженПроверитьИнформацияОбОшибкеСПричиной"); ВсеТесты.Добавить("Тест_ДолженПроверитьОбъединениеПутей"); @@ -888,6 +889,50 @@ ВызватьИсключение "Исключение не было брошено"; КонецПроцедуры +Процедура Тест_ДолженПроверитьИнформацияОбОшибкеСПричиной() Экспорт + + Попытка + ВыброситьТестовоеИсключение(); + Исключение + ИнформацияОбОшибкеОригинальная = ИнформацияОбОшибке(); + КонецПопытки; + + юТест.ПроверитьИстину(ЗначениеЗаполнено(ИнформацияОбОшибкеОригинальная), "Исключение не было брошено"); + + Объект = Новый ИнформацияОбОшибке("Я новая ошибка", Новый Массив, ИнформацияОбОшибкеОригинальная); + + Попытка + ВызватьИсключение Объект; + Исключение + ИнформацияОбОшибке = ИнформацияОбОшибке(); + + юТест.ПроверитьИстину( + СтрНайти(ИнформацияОбОшибке.Описание, "Я новая ошибка") > 0, + "Описание в новой информации об ошибке должно быть текстом из конструктора" + ); + + юТест.ПроверитьТип( + ИнформацияОбОшибке.Причина, + "ИнформацияОбОшибке", + "У информации об ошибке которому передали причину в конструкторе, + |должна быть заполнена причина после выброса исключения" + ); + + юТест.ПроверитьРавенство( + ИнформацияОбОшибке.Причина, + ИнформацияОбОшибкеОригинальная, + "Причина в новой информации об ошибке должна соответствовать переданной в конструктор" + ); + + юТест.ПроверитьИстину( + СтрНайти(ИнформацияОбОшибке.Причина.Описание, "тест-тест-тест") > 0, + "Оригинальное сообщение должно содержать текст исключения" + ); + + КонецПопытки; + +КонецПроцедуры + Процедура Тест_ДолженПроверитьОбъединениеПутей() Экспорт СИ = Новый СистемнаяИнформация(); Если Найти(СИ.ВерсияОС,"Windows") > 0 Тогда