Are there any cases when error 500 is acceptable to be returned? Or should we always try to handle all server-side exceptions and return another code with a user-friendly informative error message?
No. If you ask a normal person (i.e. a non geek) they will most likely think that they have done something wrong. You should always try and be as user friendly as possible. Also the stack trace should never be visible in a production system as that is exactly what hackers are looking for.
One thing we used to do was in a test environment was to surface the stack trace in the HTML source as comments so the test automation can easily access it.
Also I have seen white text on white background to display the text in production, so you only needed to highlight the white section to see it, but this is a bad idea as most hackers will use their own client side source, not yours.
From the question I'm understanding that you are asking if it is okay to allow the default white page with critical information of probably the page and line number of the code where the error occurred to display in the front-end/production environment/user side.
Simplest and most appropriate answer (as per my understanding) is NO.
The reason being this discloses critical data which malicious users (hackers) like to exploit. Instead of this have a custom error page for error status codes like 500, 503, 404, 403 and any other error status and wherever such an error occurs redirect users to the respective custom error page which will display a custom and more user friendly error message.
The wording of the question and the answers seem to miss a subtlety in what you're asking. To not break HTTP, you should always return as a 500. You never redirect to an error page (and give a 200 OK if something bad happened).
Now, whether or not you're bubbling up the stack trace, or just giving a simple "something bad happened" - that's another story. Web and app server trickery can be used to mask the specifics while still returning the proper HTTP status code. So the simple answer is yes return 500, but yes swallow the exception details before delivering the page to the end user.
In production, our web application shows a friendly message. While manual testing, we set a test flag that allows a stack trace to appear in the browser. When we are penetration testing or stress testing, we surface the HTTP 500.
Our applications display a user-friendly message to the user with an error code in brackets beside it to avoid the "Error hiding" design anti-pattern. In the particular case of a server timeout I use (500) beside the friendly text message that "There was a problem completing your request please try again later.", etc.. This is a friendly message to the user but also allows a technician to know what type of failure occurred if the user contacts us about it.