我正在编写一个C#应用程序(在Linux中使用mono,但这应该没关系)我正在使用duplicati dll进行编程。我希望程序永远不会崩溃所以我试图捕获每个异常。问题现在是抛出一个异常,我无法抓住它。也许来自一个帖子?!?
旁注:仅出于测试目的,我故意尝试备份到我没有权限的位置。如果我给予许可,那么我没有错误。
代码如下所示:
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
为什么我无法捕捉到所有异常?我做错了吗?
答案 0 :(得分: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,所以我使用了GitHub主分支的HEAD。
答案 1 :(得分:1)
catch
块可能会抛出异常吗?
无论如何,@ gunr2171想法的变体 - 创建一个单独的Vis。具有单个文件(类)的Studio项目及其所做的只是调用包含在try/catch
中的主程序;所以这是应用程序的最顶层。
如果您的库是线程化的,它应该公开一些东西来测试线程异常;很像BackgroundWorker.RunWorkerCompleted
event。
注册AppDomain.UnhandledException事件
值得捕捉
自由使用Exception.Data
属性。有时我会明确地在我的课程中覆盖ToString()
,以便将其投入Exception.Data
。
在应用程序正文中尽可能地捕获(这似乎是OP所做的)。此上下文将帮助您在Exception.Data
中捕获特别相关的信息。阅读库的 - 和.NET - 文档。
在应用程序的顶部有一个通用的try/catch
。
避免重新捕捉不会添加上下文的层。
重新投掷: throw e
将堆栈跟踪丢弃到该点。而是throw
。
让您的应用程序更加健壮
null
字符串。以下是我最喜欢的实时生产代码:if(string.IsNullOrEmpty(myString.Trim()))
一些希望有用的链接
Catching Unhandled exceptions on separate threads