First of all, I would disagree with this statement:
Favour exceptions over error codes
This is not always the case: for example, take a look at Objective-C (with the Foundation framework). There the NSError is the preferred way to handle errors, despite the existence of what a Java developer would call true exceptions: @try, @catch, @throw, NSException class, etc.
However it is true that many interfaces leak their abstractions with the exceptions thrown. It is my belief that this is not the fault of the "exception"-style of error propagating/handling. In general I believe the best advice about error handling is this:
Deal with the error/exception at the lowest possible level, period
I think if one sticks to that rule of thumb, the amount of "leakage" from abstractions can be very limited and contained.
On whether exceptions thrown by a method should be part of its declaration, I believe they should: they are part of the contract defined by this interface: This method does A, or fails with B or C.
For example, if a class is an XML Parser, a part of its design should be to indicate that the XML file provided is just plain wrong. In Java, you normally do so by declaring the exceptions you expect to encounter and adding them to the throws
part of the declaration of the method. On the other hand, if one of the parsing algorithms failed, there's no reason to pass that exception above unhandled.
It all boils down to one thing:
Good interface design.
If you design your interface well enough, no amount of exceptions should haunt you.
Otherwise, it's not just exceptions that would bother you.
Also, I think the creators of Java had very strong security reasons to include exceptions to a method declaration/definition.
One last thing: Some languages, Eiffel for example, have other mechanisms for error handling and simply do not include throwing capabilities. There, an 'exception' of sort is automatically raised when a postcondition for a routine is not satisfied.
There is no single proper approach to your problems even within MVC pattern so simple answer to your questions does not exist.
1 Error handling
If you are using the PDO you can change error handling by setting PDO::ATTR_ERRMODE so you don't have to use exceptions but regardless of the way errors are returned it is a programmers responsibility to handle them properly.
If your method is returning false if the user doesn't exists then the controller should check what value was returned. There is no such thing as "controller assumes" it only means that the programmer assumed and didn't check returned value.
There are different errors which should be handled in different way some of them may require only showing error message some of them may be critical (like no db connection). You can use messages, views or additional controller to handle errors.
2 The proper way to show a view
Code from your example would be usually handled by the layout (header, footer, different element placement) and by the controller (using different views depending on the request). It is not good idea to use 'include' directly rather wrap it in the method. You can also create view class which would be responsible for handling views. view != .phtml
3 Managing user rights
In MVC pattern used for web applications there is usually additional "front controller" and permission checking will be handled there. You have to check for permission with each request and each request will require access to specific controller/method if you implement proper ACL it should resolve all your problems with user rights.
Best Answer
No, no, no!
Don't mix exceptions and errors. Exceptions are, well, exceptional. Errors are not. When you ask a user to enter a quantity of a product, and the user enters "hello", it's an error. It's not an exception: there is nothing exceptional in seeing an invalid input from the user. Why can't you use exceptions in non-exceptional cases, like when validating input? Other people explained it already, and shown a valid alternative for input validation.
This also means that the user don't care about your exceptions, and showing the exceptions is both unfriendly and dangerous. For example, an exception during an execution of an SQL query often reveals the query itself. Are you sure you want to take a risk to show such message to everyone?
Wrong. As a user, I don't need to know your database issues, duplicate entries, etc. I really don't care about your problems. What I do need to know is that I entered a username which already exist. As already said, a wrong input from me must trigger an error, not an exception.
How to output those errors? It depends on the context. For an already used username, I would like to see a small red flag appearing near the username, before even submitting the form, saying that the username is already used. With no JavaScript, the same flag must appear after submission.
For other errors, you would show a full page with an error, or choose another way to inform the user that something went wrong (for example a message which will appear, then fade away at the top of the page). The question is then related more to user experience than to programming.
From programmers point of view, depending of the type of the error, you will propagate it in different ways. For example, in a case of a username already taken, an AJAX request to
http://example.com/?ajax=1&user-exists=John
will return a JSON object indicating:The second point is important: you want to be sure that the same message appear both when submitting the form with JavaScript disabled and typing a duplicate username with JavaScript enabled. You don't want to duplicate the text of the error message in server-side source code and in JavaScript!
This is actually the technique used by Stack Exhange websites. For example if I try to upvote my own answer, the AJAX response contains the error to display:
You can also choose another approach, and preset the errors in the HTML page before the form is filled. Pros: you don't have to send the error message in AJAX response. Cons: what about accessibility? Try to browse the page without CSS, and you'll see all the possible errors appear.