Hard and fast rules are tough, given the number of ways we use libraries, packages, or whatever you want to call them. I think the best advice is to a) Don't Repeat Yourself, b) Add just enough to do the job; no more and c) design orthogonally. For more such advice (and more well written explanations, pick up a copy of The Pragmatic Programmer.
How much functionality should the library encapsulate ?
As much as is needed for the basic operations, no more. Going beyond that increases the amount of testing, risks sidetracking you on none-core issues, and can (in certain cases) confuse your intended audience. In turn, these prevent your library from being re-used...hindering the very laziness that led you to create the library in the first place.
Remember, you'll be using this over time. You don't need to build in every bit of functionality up front. Let it evolve as it needs to.
Is it better to make ALL the functions that are related to a common goal available to the application programmer OR should i mask these behind 1 or 2 method calls ?
I like to keep the core library as basic and streamlined as possible, providing "wrapper" functions in a separate file and/or subclass. I find this provides me the convenience of the quick access while allowing more control when needed.
Or should i do both and really complicate things ?
No; see above...unless you're independently wealthy, not planning on releasing it soon, or really don't want to re-use it. :-)
Who is responsible for error handling and error resolving ?
Depends on the interface. I've had good luck making the core routines provide return values indicating success/failure and leaving the presentation of the errors to the wrapper classes/calling code.
Should the library trap any foreseeable error and deal with it OR should this be left to the application programmer ?
Depends on how critical the error is to the library and how serious an error it is. If it's a reasonably silly error (mistyped filename, for example), I return failure using an error code. If the system is out of resources or some other catastrophic failure, I'll probably generate the error myself. Keep in mind that most languages provide different levels of error-generation. For example, Perl offers the lovely Carp module, which (thanks to Tilly) I've been playing with recently.
Be very careful with fatal error handling in your libraries. To illustrate, I wrote a package not too long ago that made file handling a lot easier in a certain context, except I got carried away and over-engineered the error handling, localizing it to the core subroutines. If a file wasn't found, I called die().
A few days later, I called my routine from a bit of code that didn't really care that the file didn't exist. However, because the file didn't exist, the error handler stopped the program cold, forcing me to either re-work the package or to add a handler to detect that error and recover from it "gracefully." I chose the former and it saved a chunk of code.
Your mileage will vary, or course, based on the library and problem(s) it solves. As with other code, though, I've found the LAW (Least Amount of Work) principle helpful.
--f