Never throw exceptions from destructors.
Maintain some basic level of exception guarantees about the state of the object.
Do not use exceptions to communicate errors which can be done using an error code unless it is a truly exception error and you might want the upper layers to know about it.
Do not throw exceptions if you can help it. It slows everything down.
Do not just catch(...) and do nothing. Catch exceptions you know about or specific exceptions. At the very least log what happened.
When in the exception world use RAII because nothing is safe anymore.
Shipping code should not have suppressed exceptions at least with regards to memory.
When throwing exceptions package as much information as is possible along with it so that the upper layers have enough information to debug them.
Know about flags that can cause libraries like STL to throw exceptions instead of exhibiting unknown behaviour (e.g. invalid iterators / vector subscript overflow).
Catch references instead of copies of the exception object?
Take special care about reference counted objects like COM and warp them in reference counted pointers when working with code that could throw exceptions.
If a code throws an exception more than 2% of the time consider making it an error code for performance's sake.
Consider not throwing exceptions from undecorated dll exports / C interfaces because some compilers optimize by assuming C code to not throw exceptions.
If all that you do for handling exceptions is something akin to below, then don't use exception handling at all. You do not need it.
main
{
try {
all code....
}
catch(...) {}
}