diff --git a/src/OneScript.StandardLibrary/Tasks/BackgroundTask.cs b/src/OneScript.StandardLibrary/Tasks/BackgroundTask.cs index fdf1793ce..f56a59833 100644 --- a/src/OneScript.StandardLibrary/Tasks/BackgroundTask.cs +++ b/src/OneScript.StandardLibrary/Tasks/BackgroundTask.cs @@ -111,6 +111,7 @@ public void ExecuteOnCurrentThread() catch (ScriptException exception) { State = TaskStateEnum.CompletedWithErrors; + exception.RuntimeSpecificInfo = MachineInstance.Current.GetExecutionFrames(); ExceptionInfo = new ExceptionInfoContext(exception); } } diff --git a/src/ScriptEngine/Machine/Contexts/StackTraceCollectionContext.cs b/src/ScriptEngine/Machine/Contexts/StackTraceCollectionContext.cs index 6506c9b45..4599a6200 100644 --- a/src/ScriptEngine/Machine/Contexts/StackTraceCollectionContext.cs +++ b/src/ScriptEngine/Machine/Contexts/StackTraceCollectionContext.cs @@ -8,6 +8,7 @@ This Source Code Form is subject to the terms of the using System.Collections.Generic; using System.Linq; using OneScript.Contexts; +using OneScript.Exceptions; namespace ScriptEngine.Machine.Contexts { @@ -30,6 +31,11 @@ internal StackTraceCollectionContext(IEnumerable frames) }).ToList(); } + /// + /// Возвращает количество кадров в стеке вызовов + /// + /// Число - Количество кадров в стеке вызовов + [ContextMethod("Количество", "Count")] public override int Count() { return _frames.Count; @@ -39,5 +45,23 @@ public override IEnumerator GetEnumerator() { return _frames.GetEnumerator(); } + + public override bool IsIndexed => true; + + public override IValue GetIndexedValue(IValue index) + { + var idx = (int)index.AsNumber(); + + if (idx < 0 || idx >= Count()) + throw IndexOutOfBoundsException(); + + return _frames[idx]; + } + + private static RuntimeException IndexOutOfBoundsException() + { + return new RuntimeException("Значение индекса выходит за пределы диапазона"); + } + } } diff --git a/src/ScriptEngine/Machine/MachineInstance.cs b/src/ScriptEngine/Machine/MachineInstance.cs index e342cf4aa..6dd586abe 100644 --- a/src/ScriptEngine/Machine/MachineInstance.cs +++ b/src/ScriptEngine/Machine/MachineInstance.cs @@ -2451,6 +2451,7 @@ private IValue PopRawValue() public IList GetExecutionFrames() { + CreateFullCallstack(); return _fullCallstackCache; } diff --git a/tests/tasks.os b/tests/tasks.os index e0c006dca..1cc7f878b 100644 --- a/tests/tasks.os +++ b/tests/tasks.os @@ -24,6 +24,7 @@ ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоВозвращаетсяРезультатДелегата"); ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоРаботаетБлокировка"); ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоКодМожетОпределитьИДЗадания"); + ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоВИнформацииОбОшибкеЕстьСтекВызовов"); ВсеТесты.Добавить("ТестДолжен_ПроверитьЧтоОбработчикиСобытийВызываютсяВФоновомЗадании"); Возврат ВсеТесты; @@ -271,6 +272,23 @@ КонецПроцедуры +Процедура ТестДолжен_ПроверитьЧтоВИнформацииОбОшибкеЕстьСтекВызовов() Экспорт + + Задание = ФоновыеЗадания.Выполнить(ЭтотОбъект, "ПроцедураСИсключением"); + Задание.ОжидатьЗавершения(); + + СтекВызовов = Задание.ИнформацияОбОшибке.ПолучитьСтекВызовов(); + + юТест.ПроверитьТип(СтекВызовов, "КоллекцияКадровСтекаВызовов"); + + юТест.ПроверитьРавенство(СтекВызовов.Количество(), 1); + + юТест.ПроверитьРавенство(СтекВызовов[0].Метод, "ПроцедураСИсключением"); + юТест.ПроверитьЗаполненность(СтекВызовов[0].НомерСтроки); + юТест.ПроверитьРавенство(СтекВызовов[0].ИмяМодуля, ТекущийСценарий().Источник); + +КонецПроцедуры + Процедура ТестДолжен_ПроверитьЧтоОбработчикиСобытийВызываютсяВФоновомЗадании() Экспорт СобытиеВызвано = Ложь;