Илья Фофанов "Обработка ошибок в c#"
TRANSCRIPT
![Page 1: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/1.jpg)
1
IOA Error Panel
PLEASE PRESS ENTER TO RESUME
Обработка ошибок в C#
MSK.NET представляет
ERROR
![Page 2: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/2.jpg)
2
Илья Фофанов
http://engineerspock.com
![Page 3: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/3.jpg)
3
Зачем надо уметь обрабатывать ошибки?
• Бич современности: падающие приложения, которые ничего не сообщают о возникшей проблеме
• Обработка ошибок – критически важная часть программ с высокими требованиями к устойчивости
![Page 4: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/4.jpg)
4
Проверяемые Непроверяемые
![Page 5: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/5.jpg)
Большие проблемы… с исключениями
5
![Page 6: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/6.jpg)
6
Виды ошибок
![Page 7: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/7.jpg)
7
Как бороться с исключениями
![Page 8: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/8.jpg)
8
public HttpResponseMessage CreateCustomer(string name, string billingInfo) {
Result<BillingInfo> billingInfoResult = null; try { billingInfoResult = BillingInfo.Create(billingInfo); } catch (Exception ex) { Log(ex); return CreateResponseMessage(ex); } Result<CustomerName> customerNameResult = null; try { customerNameResult = CustomerName.Create(name); } catch (Exception ex) { Log(ex); return CreateResponseMessage(ex); } try { _paymentGateway.ChargeCommission(billingInfoResult.Value); } catch (Exception ex) { Log(ex); return CreateResponseMessage(ex); }
var customer = new Customer(customerNameResult.Value); try { _repository.Save(customer); } catch (Exception ex) { Log(ex); _paymentGateway.RollbackLastTransaction(); } try { _emailSender.SendGreetings(customerNameResult.Value); } catch (Exception ex) { Log(ex); return CreateResponseMessage(ex); } return CreateResponseMessage(true);}
«Try-Catch» Hell
![Page 9: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/9.jpg)
9
public HttpResponseMessage CreateCustomer(string name, string billingInfo){ Result<BillingInfo> billingInfoResult = BillingInfo.Create(billingInfo); Result<CustomerName> customerNameResult = CustomerName.Create(name); return Result.Combine(billingInfoResult, customerNameResult) .OnSuccess(() => _paymentGateway.ChargeCommission(billingInfoResult.Value)) .OnSuccess(() => new Customer(customerNameResult.Value)) .OnSuccess(customer => _repository.Save(customer) .OnFailure(() => _paymentGateway.RollbackLastTransaction())) .OnSuccess(() => _emailSender.SendGreetings(customerNameResult.Value)) .OnBoth(Log) .OnBoth(CreateResponseMessage);}
«No Try-Catch» Paradise
![Page 10: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/10.jpg)
10
Семь бед - один ответ: исключения!
![Page 11: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/11.jpg)
11
Use exceptions. They are much cleaner then all the other options. The fear about uncaught exceptions is misplaced. Forgetting to catch an exception is much better than forgetting the if statement to check a result. The former fails visibly, and the latter fails silently. The fear of messy code near the try/catch blocks is also misplaced. Use the 'extract till you drop' rule, and make sure that any function with a try/catch block has _only_ the try/catch block in it; with the try block being a single function call.Finally, write tests for all your exception throws, and all your exception catches. Error processing is part of the legitimate behavior of your system and testing it is very important.
Robert Martin aka “Uncle Bob”
“
https://groups.google.com/forum/#!topic/clean-code-discussion/CQSA4czDvHc
![Page 12: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/12.jpg)
12
Проблемы исключений
![Page 13: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/13.jpg)
13
Пример проверяемого исключения
public static void readFile(string filePath) throws IOException { FileReader file = new FileReader(filePath); BufferedReader fileInput = new BufferedReader(file); // Print first 3 lines of the file for (int counter = 0; counter < 3; counter++) System.out.println(fileInput.readLine()); fileInput.close(); }
![Page 14: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/14.jpg)
14
Проблема масштабирования
![Page 15: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/15.jpg)
15
Проблема версионирования
Нельзя просто так взять
и добавить новый тип исключения
![Page 16: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/16.jpg)
16
Какое решение?
Выпилить проверяемые исключения!
![Page 17: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/17.jpg)
17
Трудно понять программу
![Page 18: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/18.jpg)
18
Their power comes at an extremely high cost; it becomes impossible to understand the flow of the program using only local analysis; the whole program must be understood. This is especially true when you mix exceptions with more exotic control flows like event-driven or asynchronous programming. Avoid, avoid, avoid; use exceptions only in the most exceptional circumstances, where the benefits outweigh the costs.
Eric Lippert
“
![Page 19: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/19.jpg)
19
“…people don't care. They're not going to handle any of these exceptions. There's a bottom level exception handler around their message loop. That handler is just going to bring up a dialog that says what went wrong and continue.”
“It is funny how people think that the important thing about exceptions is handling them. That is not the important thing about exceptions. In a well-written application there's a ratio of ten to one, in my opinion, of try finally to try catch.”
Anders Hejlsberg
“
![Page 20: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/20.jpg)
20
Как обезопасить себя при чтении файла?
try { File.ReadAllLines();}catch (?) { }
![Page 21: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/21.jpg)
21
Исключения из File.ReadAllLines()• ArgumentException• ArgumentNullException• PathTooLongException• NotSupportedException
• IOException• DirectoryNotFoundException• FileNotFoundException
• UnathorizedAccessException• SecurityException
![Page 22: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/22.jpg)
22
Знаем ли мы какие исключения перехватывать?
![Page 23: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/23.jpg)
23
Corrupted State Exceptions
![Page 24: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/24.jpg)
24
SEHException
Если CLR не знает, что делать с исключением из unmanaged кода, то CLR заворачивает его в тип SEHException.
![Page 25: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/25.jpg)
25
Corrupted State ExceptionCorrupted State Exception (CSE) – исключение связанное с поврежденным состоянием.
Примеры CSE в C#:• SEHException• AccessViolationException
CSE в unmanaged:• EXCEPTION_ILLEGAL_INSTRUCTION EXCEPTION_IN_PAGE_ERROR• EXCEPTION_INVALID_DISPOSITION
EXCEPTION_NONCONTINUABLE_EXCEPTION• EXCEPTION_ACCESS_VIOLATION EXCEPTION_STACK_OVERFLOW• EXCEPTION_PRIV_INSTRUCTION STATUS_UNWIND_CONSOLIDATE
![Page 26: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/26.jpg)
26
CSE. Надо ли ловить?
• В общем случае ловить CSE не надо. Компенсационную логику написать практически невозможно.
• Можно ловить только в случаях, когда вы точно знаете с какой проблемой столкнулись и уверены, что можно «подавить и продолжить»
![Page 27: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/27.jpg)
27
CSE. Как поймать?[HandleProcessCorruptedStateExceptions]public static void HandleCorruptedState(){ // handling}
<configuration> <runtime> <legacyCorruptedStateExceptionsPolicy enabled="true"/> </runtime></configuration>
1.
2.
![Page 28: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/28.jpg)
28
Обработка исключений
![Page 29: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/29.jpg)
29
Обработка только известных исключений
try { File.ReadAllLines();}catch (IOException ex) { } //а точно ничего не забыли?
![Page 30: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/30.jpg)
30
Политики фильтраций
try { File.ReadAllLines();}catch (Exception ex) { //делегируем обработку ExceptionManager .HandleException(ex, “Policy”);}
![Page 31: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/31.jpg)
31
Catch Them All!
try { File.ReadAllLines();}//вообще всё пофигу!catch (Exception ex) { }
![Page 32: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/32.jpg)
32
Подавление исключений
1. Приложение какого типа вы разрабатываете? 2. Полной корректности достичь очень трудно.3. Каков размер приложения?
![Page 33: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/33.jpg)
33
… most people don’t write robust error handling code in non-systems programs, throwing an exception usually gets you out of a pickle fast. Catching and then proceeding often works too. No harm, no foul. Statistically speaking, programs “work.”Joe Duffy
“
![Page 34: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/34.jpg)
34
Категории ошибок
Пользовательские восстанавливаемые
Системные восстанавливаемые
Пользовательские невосстанавливаемые
Системные невосстанавливаемые
Пользовательские Системные
Восс
тана
влив
аем
ые
Нево
сста
навл
ивае
мы
е
![Page 35: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/35.jpg)
35
Восстанавливаемые пользовательские ошибки
public void TransferMoney(Payment p) { if (p == null) throw new ArgumentNullException("p"); ValidatePayment(p);}
![Page 36: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/36.jpg)
36
Исключения и сигнатура метода
Эту семантическую часть надо вывести в сигнатуру метода!
• Исключения – побочные эффекты
• Исключения, выражающие нарушения пользовательской бизнес-логики скрывают важную семантическую часть
![Page 37: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/37.jpg)
37
Боремся с исключениями
![Page 38: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/38.jpg)
38
Способы борьбы с исключениями
• Шаблон Tester-Doer• Шаблон TryParse• Railway Oriented Programming
![Page 39: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/39.jpg)
39
Tester-Doer
ICollection<Student> students = GetStudents();if (!students.IsReadOnly)//tester{ students.Add(new Student("Joe")); //doer}
![Page 40: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/40.jpg)
40
TryParse
DateTime birthday;bool parsed = DateTime.TryParse("12/08/1988", out birthday);if (parsed) { SocialNumber socialNumber; parsed = SocialNumber.TryParse("1239584594", out socialNumber); if (parsed) { } else { }}else {}
![Page 41: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/41.jpg)
41
Недостатки Tester-Doer и TryParse
• Tester-Doer – форма антипаттерна «temporal coupling»• Tester-Doer не работает в условиях конкурентного доступа• TryParse неуклюж из-за out-параметра и возврата boolean
![Page 42: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/42.jpg)
42
Pipelining
[| 83uy; 80uy; 79uy; 67uy; 75uy |]|> Encoding.ASCII.GetString(textInBytes)|> Console.WriteLine(contents)
var sb = new StringBuilder();sb.Append("Hello") .Append(",") .Append("World") .AppendLine("!");
Pipelining in F# Method chaining in C#
![Page 43: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/43.jpg)
43
Коды ошибок
![Page 44: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/44.jpg)
44
Демо
![Page 45: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/45.jpg)
4 вида методовCommands:
Queries:
void EnrollStudent(Student student);//not expected to fail
Result EnrollStudent(Student student);//expected to fail
Student GetStudent(string name);//not expected to fail
Result<Student> GetStudent(string name); //expected to fail
45
![Page 46: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/46.jpg)
46
Итоги
![Page 47: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/47.jpg)
47
Что делать?
Отслеживайте control flow. Если вызов уходит в unmanaged будьте готовы к неприятностям.
Есть три основных подхода к обработке исключений. Выбирайте тот, который оптимальным образом удовлетворяет требования по устойчивости конкретного приложения.
![Page 48: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/48.jpg)
48
Категории ошибок – что делать?
Result Monad Catch\Handle or Suppress
Fail Fast or Suppress Fail Fast Only
Пользовательские Системные
Восс
тана
влив
аем
ые
Нево
сста
навл
ивае
мы
е
![Page 49: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/49.jpg)
Ссылкиhttp://pluralsight.com/courses/csharp-applying-functional-principles «Applying Functional Principles in C#» - видео курс
https://github.com/vkhorikov/CSharpFunctionalExtensionsКласс Result и полезные расширения – исходники
https://www.nuget.org/packages/CSharpFunctionalExtensions/Класс Result и полезные расширения – NuGet package
Владимир Хориков
https://www.visualstudio.com/en-us/products/visual-studio-dev-essentials-vs.aspx49
![Page 50: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/50.jpg)
Ссылкиhttps://ericlippert.com/2014/03/03/living-with-unchecked-exceptions/Статья Эрика Липперта в двух частях про исключения
https://vimeo.com/97344498Scott Wlaschin - Railway Oriented Programming — error handling in functional languages
http://www.artima.com/intv/handcuffs.htmlАндерс Хейлсберг об исключениях
http://joeduffyblog.com/2016/02/07/the-error-model/Очень крутая статья Joe Duffy об обработке ошибок
50
https://www.nuget.org/packages/EnterpriseLibrary.ExceptionHandling/Enterprise Exception Handling Block
http://sergeyteplyakov.blogspot.ru/2016/06/semantic-of-exception.htmlСтатья Теплякова об исключениях
https://github.com/App-vNext/PollyPolly
![Page 51: Илья Фофанов "Обработка ошибок в C#"](https://reader036.vdocuments.mx/reader036/viewer/2022062522/589ee66b1a28abe97f8b4a4b/html5/thumbnails/51.jpg)
Илья Фофанов
http://engineerspock.comhttps://www.udemy.com/user/eliasfofanov/https://habrahabr.ru/users/engineerspock/
51
Спасибо за внимание!