Как мога да спра DevForce да поглъща изключения в събитието EntityManager.EntityChanged

Това е още едно продължение на тема от форумите на DevForce тук. Проблемът е, че DevForce тихо ще погълне всяко изключение, което се хвърля от събитието EntityManager.EntityChanged, ако промяната е била задействана от заявка или импортиране. Съответният код изглежда така:

internal virtual void OnEntityChanged(EntityChangedEventArgs args)
{
    EventHandler<EntityChangedEventArgs> entityChanged = this.EntityChanged;
    if (entityChanged == null) return;
    try
    {
        entityChanged(this, args);
    }
    catch
    {
        if (args.Action != EntityAction.AddOnQuery && args.Action != EntityAction.AddOnImport)
        {
            throw;
        }
    }
}

Както бе споменато в нишката на форума, поведението на този метод се промени малко с времето. Сега се преглъщат по-малко неща, отколкото когато за първи път се оплаках от това. Но за нашето приложение наистина трябва да знаем кога нещо се обърка. Само защото се е случило да се обърка, когато съм извършил заявка или операция за импортиране, не означава, че не ме е грижа за изключението.

В последната публикация във форума обосновката за това поведение беше:

Аргументът за поглъщане на изключения, хвърлени по време на AddOnQuery (и AddOnImport), беше, че „провалът по средата на заявка обикновено не е това, което разработчикът всъщност е възнамерявал“, защото е по-вероятно да се случи поради лошо написан манипулатор на събития

Може би не сме обикновени :-), но в нашето приложение манипулаторът на събития изглежда така:

EntityManager.EntityChanged += (sender, e) =>
{
    if (e.Action == EntityAction.AddOnAttach ||
        e.Action == EntityAction.AddOnImport ||
        e.Action == EntityAction.AddOnQuery)
    {
        ((MyBaseClass) e.Entity).Initialize();
    }
};

Всяко изключение, хвърлено тук, няма да е поради лошо написан манипулатор на събития. Всяко изключение, което се хвърля тук, е, защото обектът се е объркал много, докато е изпълнявал логиката си за еднократна инициализация. И грешките в тази логика са много важни за нас.

Разбирам, че универсалната промяна на това може да е опасна и да доведе до счупване на други приложения. Но ако имаше някакъв начин, по който можем да изключим това поведение или някакъв друг начин да кажем на Entity Manager да не преглъща изключението, това би било много, много полезно.

Нашите предишни заобиколни решения започват да се провалят, тъй като търсим да използваме цялата си бизнес логика в уеб услуга, където не можем да разчитаме само на регистриране на грешки, за да се справим с този вид неща. Не можем да връщаме отговор „успех“ на повикващия само защото DevForce е погълнал потенциално фатална грешка.

Ние сме на най-новата версия на DevForce (към писането на това: 2012 - 7.2.3).


person Stephen McDaniel    schedule 22.07.2014    source източник
comment
Можем да преразгледаме това. Ако се окаже, че изключенията се поглъщат поради някакво друго неправилно поведение на DevForce, тогава не мисля, че ще променим тази логика; но в противен случай това може да е нещо, което можем да разгледаме в следващото издание.   -  person Kim Johnson    schedule 23.07.2014
comment
От това, което мога да кажа (приемете това със зрънце сол, предполагам), събитието EntityChanged изобщо не се използва от DevForce...така че не мисля, че трябва да се тревожим, че тази промяна засяга стандартното поведение на DevForce .   -  person Stephen McDaniel    schedule 23.07.2014
comment
@KimJohnson Кога ще разберете дали това влиза в следващото издание или не? И може би дори как сте възнамерявали да го поправите? Искам да планирам малко по-напред - ако се окаже, че това няма да бъде поправено в DevForce (или е поправено по начин, който в крайна сметка не решава всичките ни проблеми), трябва да се върна към чертожната дъска.. .   -  person Stephen McDaniel    schedule 24.07.2014
comment
Планирано е за изданието 7.2.4, но все още не е готово. Вероятно можем да ви предоставим RC версия в началото на следващата седмица.   -  person Kim Johnson    schedule 25.07.2014
comment
Е, това поведение има дълга и византийска история отпреди 5 години и най-простият подход, без да си прави труда да хване и изяде тези изключения, вероятно не е осъществим. Бихте ли направили методите OnEntityChanging/Changed на EntityManager заменими да работят за вас? Ако все пак искате да извикате вашите манипулатори от вашите заменени методи, ние също можем да добавим помощни методи, за да го направим.   -  person Kim Johnson    schedule 29.07.2014
comment
Проблемът, който имам с тази опция, е, че когато правя неща като извикване на InvokeServerMethod или съм в извикване на EntityServerSaveInterceptor, всички обекти не са в нашия персонализиран/извлечен EM клас - те са в „ванилен“ EM. Поради тази причина се опитахме да избегнем да правим нещо специално в нашия персонализиран клас на мениджър на обекти, защото не винаги контролираме мениджъра на обекти. Ако имаше опция, при която мога да контролирам това извън EM, това би било идеално - персонализиран флаг на EM, който включвам, глобална настройка в IdeaBladeConfig, персонализиран делегат, който предоставям на EM, ...   -  person Stephen McDaniel    schedule 29.07.2014
comment
Добре, тогава какво ще кажете за нов флаг на EntityManager.Options?   -  person Kim Johnson    schedule 29.07.2014
comment
Това би било перфектно!   -  person Stephen McDaniel    schedule 29.07.2014
comment
Компилация 7.2.4 rc3 с тази промяна вече е на ftp сайта на IdeaBlade. Тази компилация също така включва възможност за изключване или персонализиране на автоматичен повторен опит, но мога да обясня как работи това в другата ви нишка, ако имате въпроси. Както при предишната rc компилация, ще трябва да изчистите кеша на източника на пакет NuGet, тъй като имената на пакетите не са променени.   -  person Kim Johnson    schedule 30.07.2014


Отговори (1)


Версия 7.2.4 съдържа флаг, EntityManagerOptions.ThrowAllLoadExceptions, за контролиране на това поведение. Бележки по версията.

person Kim Johnson    schedule 05.08.2014
comment
Надградихме до 7.2.4 и тази опция работи перфектно за нас! - person Stephen McDaniel; 07.08.2014
comment
Току-що открихме друго място, където изключения се поглъщат и това ни създава някои големи проблеми. EntityAspect.FirePropertyChanged ще погълне изключения, ако EntityManager.IsLoadingEntity е вярно. Това изглежда като друго място, където EntityManagerOptions.ThrowAllLoadExceptions трябва да презапише това поведение. Доколкото разбирам, този случай е „изключение при натоварване“. Има ли логика в това? - person Stephen McDaniel; 26.06.2015
comment
Прав си, всякакви изключения при зареждане и тук се преглъщат. Добре, трябва да можем да поправим това в следващото издание (7.2.7). - person Kim Johnson; 27.06.2015
comment
И ако има други места, където изключенията биха били преглъщани по този начин... би било хубаво и те да се актуализират. Сега се натъкнахме на два случая „случайно“... Не съм сигурен колко други случая може да има. - person Stephen McDaniel; 29.06.2015
comment
Най-хубавото от всичко би било тази странна логика на преглъщане изобщо да не е била писана, но сте прав, че корекциите също са били доста случайни. Този път ще се опитаме да вземем всичко. - person Kim Johnson; 29.06.2015