2015-06-25 3 views
0

Я пишу приложение C# (в Linux с моно, но это не должно иметь значения), и я программирую с dll duplicati. Я хочу, чтобы программа никогда не вылетала, поэтому я пытался поймать каждое исключение. Проблема в том, что исключение выбрасывается, и я не могу его поймать. Может, из нитки?!?C# не удалось поймать все исключения

Sidenote: Только для целей тестирования я намеренно попытался выполнить резервное копирование в Место, где у меня нет разрешения. Если я дам разрешение, то я не получу ошибки.

код выглядит следующим образом:

try { 
    Interface i = new Interface(backend, options); 
    result = i.Backup(folders.ToArray()); 
} catch (Exception e) { 
    //Write to log. 
    //Here is no throw; !! 
} 

я получаю трассировку стека:

Error : System.Exception: Failed to retrieve file listing: Access to the path "/home/pi/test" is denied. ---> System.UnauthorizedAccessException: Access to the path "/home/pi/test" is denied. 
    at System.IO.Directory.GetFileSystemEntries (System.String path, System.String searchPattern, FileAttributes mask, FileAttributes attrs) [0x00000] in <filename unknown>:0 
    at System.IO.Directory.GetFiles (System.String path, System.String searchPattern) [0x00000] in <filename unknown>:0 
    at System.IO.Directory.GetFiles (System.String path) [0x00000] in <filename unknown>:0 
    at Duplicati.Library.Backend.File.List() [0x00000] in <filename unknown>:0 
    at Duplicati.Library.Main.BackendWrapper.ListInternal() [0x00000] in <filename unknown>:0 
    --- End of inner exception stack trace --- 
    at Duplicati.Library.Main.BackendWrapper.ListInternal() [0x00000] in <filename unknown>:0 
    at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (System.Reflection.MonoMethod,object,object[],System.Exception&) 
    at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0 

Почему я не могу поймать все исключения? Я делаю что-то неправильно?

+2

Относительно не связанных друг с другом: некоторые исключения являются более исключительными, чем другие, например StackOverflow ... Вернуться к вопросу - стек действительно не соответствует показанному коду - так сложно предложить что-либо, но действительно исключения, брошенные на другой поток, не будут быть пойманным этим кодом. –

+0

какая строка ошибка? –

+0

Не все исключения подлежат возмещению. предположим, что это исключение происходит, оно вырывается из вашего кода и переходит к обработчику. где должна возобновиться ваша программа? – CThin

ответ

1

Блок catch исключает, возможно,?

В любом случае, вариант идеи @ gunr2171 - создать отдельный Vis. Проект Studio с одним файлом (классом) и все, что он делает, - это вызов основной программы, завернутой в try/catch; так что это находится на самой вершине приложения.

Если ваша библиотека имеет резьбу, она должна выставить что-то для тестирования для исключения потока; очень похоже на BackgroundWorker.RunWorkerCompleted event.


Регистрация с событием AppDomain.UnhandledException

A simple tutorial


Worthwhile исключение ловли

сделать либеральное использование Exception.Data собственности. Иногда я переопределяю ToString() в своих классах специально для того, чтобы бросить это в Exception.Data.

Поймать как можно практически в теле приложения (что, по-видимому, делает OP). Этот контекст поможет вам получить особенно важную информацию в Exception.Data. Прочитайте библиотеку - и .NET - документацию.

Имейте универсальный try/catch в верхней части приложения.

Избегайте слоев перехвата, которые не добавляют контекст.

Re-Throwing:throw e отбрасывает трассировку стека до этой точки. throw.


сделать приложение надежным

  • Определить состояние по умолчанию.The null object pattern
  • Заставлять клиентов использовать ваши конструкторы. Не подвергайте свойства и ожидайте, что клиенты будут правильно инициализироваться. Alan Kay сказал, что раскрытие свойств (состояния) не является объектно-ориентированным программированием.
  • Ненавижу null строки. Вот моя любимая линия реального живого кода производства: if(string.IsNullOrEmpty(myString.Trim()))

Некоторые мы надеемся, полезные ссылки

3
Error : System.Exception: Failed to retrieve file listing: Access to the path... 

Ну, это удалось исключение, и вы должны быть в состоянии поймать его, период. Duplicati использует Interop для родных библиотек, а сбой в этом вызове - это то, где создается стек вызовов, но он разматывается и распространяется через стек управляемых вызовов.

Я написал очень быстрый пример Duplicati, и он ловит все исключения ...

Не исключение:

mono HelloDup.exe "/tmp" 
File: Local folder or drive 

Исключение поймал:

ls /home/private/privateinfo 
ls: : Permission denied 
mono HelloDup.exe "/home/private/privateinfo" 
Exception: Access to the path "/home/private/privateinfo" is denied.: Type:System.UnauthorizedAccessException 

Исключение поймал:

mono HelloDup.exe "/foobar" 
Exception: The folder /foobar does not exist: Type:Duplicati.Library.Interface.FolderMissingException 

Исключение поймал:

ls -l /noperms/private.txt 
--w------- 1 root wheel 0 Jun 25 14:16 /noperms/private.txt 
mono HelloDup.exe "/noperms/private.txt" 
Exception: The folder /noperms/private.txt does not exist: Type:Duplicati.Library.Interface.FolderMissingException 

Пример кода:

try { 
    var file = new Duplicati.Library.Backend.File(args[0], options); 
    file.CreateFolder(); 
    Console.WriteLine ("File: {0}", file.DisplayName); 
} catch (Exception e) { 
    Console.WriteLine ("Exception: {0}: Type:{1}", e.Message, e.GetType()); 
} 

Следующие шаги:

Я хотел бы проверить версии Mono и Duplicati вы используете ... Если вы являются базовой системой установки Mono, вы могли бы быть действительно позади. Также я использовал xbuild для компиляции Duplicati, поэтому я использую HEAD ведущей ветки GitHub.

+0

Спасибо за ответ! Когда я копирую ваш пример кода и меняю путь к моей папке, я также могу поймать Исключение! Но НЕ, когда я использую класс Interface. Я предполагаю, что разница здесь заключается в том, что при использовании 'Backend.File' Исключение происходит непосредственно, но при использовании' Interface' исключение генерируется в другом потоке. –

+0

Интересно. Какую версию моно вы используете? (моноверсия), а также какую архитектуру? x86 или amd64/x86_64? Кроме того, interop-вызов в C vs C++ приведет к различной обработке исключений, поскольку C не имеет обработки исключений, в то время как C++ может, но он отличается от управляемого исключения ... он становится сложным быстро ;-) – SushiHangover

+0

Я использую моно версию 3.2. 8. Моя архитектура ARMv6 (Raspberry :-)) Возможно, это проблема здесь! Да, очень сложно ... –

Смежные вопросы