Thread: Avisynth+
View Single Post
Old 9th October 2013, 14:13   #140  |  Link
ultim
AVS+ Dev
 
ultim's Avatar
 
Join Date: Aug 2013
Posts: 359
Avisynth Plugin Writing Tips #1: Exceptions

Exceptions thrown from a module should only be caught in the same module. Otherwise you can experience weird and hard-to-debug errors in the plugin. Not adhering to this advice will result in code that can sporadically fail, or work on your computer consistently but fail on other machines.

Unfortunately, avisynth.h contains the AvisynthError class, giving plugin authors the false impression that it is safe to throw and catch these exception objects. It is not. The problem is not in the definition of this class, but in the implicit encouragement to throw C++ exceptions across DLL boundaries. Here are some tips to avoid getting caught in the deepest pits of hell:
- When throwing exceptions on your own, it is best not to use AvisynthError. Not using it will stop you thinking that AvisynthError has some special meaning, or that it can be used to throw to (or to catch from) avisynth.dll.
- Exceptions thrown by you should always be caught inside your plugin. You should not let exceptions propagate outside of your DLL (unless thrown using ThrowError), to Avisynth.
- Errors thrown by Avisynth should not be caught by you. In specific, don't wrap calls to Avisynth in try-catch blocks, because you cannot rely on it working correctly in every situation. If you need to detect errors, validate user parameters in your plugin, or use other API facilities provided by Avisynth, like IScriptEnvironment->FunctionExists().
- If you want to throw an exception to the user and/or to Avisynth, then only use IScriptEnvironment->ThrowError(). You should not call C++'s "throw" yourself for this purpose (see 2. point), and you should not catch the error thrown by ThrowError() yourself (see 3. point).
- If you want to catch an exception, want to do something based on that and finally raise an exception to Avisynth, don't rethrow. Catch your own exception (unless thrown by ThrowError), then call ThrowError separately.

Ignoring the above tips can still result in a fully working binary, but that is only guaranteed under very specific circumstances, more specifically when you've compiled your plugin with the *exact* same compiler version as the avisynth.dll was compiled with, AND when linking to the CRT runtime dynamically. Given that plugin authors can use whatever compiler they want, and that an avisynth binary can be supplied by any community member, it is unwise to rely on such detail.

These tips apply to all Avisynth versions (e.g. to 2.5 and to 2.6, to "classic" Avisynth and to Avisynth+, etc).

Last edited by ultim; 25th October 2013 at 21:18.
ultim is offline