It depends on the exception. If you expect that the exception may occur and it is valid, and you are actually handling it, as in, you've got plan B for that situation, then don't throw it.
If the exception breaks the workflow and you aren't actually handling it, go ahead and log it if you deem it necessary, but sometimes the current method scope doesn't have enough useful information to justify logging it. Sometimes you'll want to throw it to a higher scope with more useful information, catch it there, then log it.
For example:
int DoSomething1(int userId, int transactionId) {
try {
int orgId = GetOrgId(userId);
DoSomething2(orgId);
/* ... more things ... */
} catch(MyException ex) {
Log(string.Format("{0}\nuser: {1}, trns: {2}\n\tMessage: {3}\n\t\tTrace: {4}",
ex.Message, userId, transactionId, ex.InnerException.Message, ex.InnerException.StackTrace));
throw;
} catch(Exception ex) {
Log(string.Format("user: {0}, trns: {1}\n\tMessage: {2}\n\t\tTrace: {3}",
userId, transactionId, ex.Message, ex.StackTrace));
throw;
}
}
int DoSomething2(int orgId) {
try {
/* ... some stuff .... */
} catch(Exception ex) {
throw new MyException { Message = string.Format("org: {0}", orgId),
InnerException = ex };
}
}
Your front-end shouldn't dump stack traces to users, so if the exception gets that far, you have to handle it one way or another. But then that depends on what the front-end is. If its a webservice, error codes are very nice instead of deceptively pretending that everything went swimmingly, or giving them no feedback at all.