Generally I'd go with throwing on any failure - it definitely leads to cleaner code (especially with errors bubbling up the stack and being handled at a convenient place). How you define "failure" then determines the behaviour. "Entry not found in that file" would depend for me on your model. If every client must have a phone number then GetPhoneNumber(Client) should throw if there isn't one in the file. Either you are throwing an ArgumentException for an invalid client, or you are throwing because there is no phone number for the client - and *something* went wrong, which needs to be fixed. If they might not have a phone number then returning null to indicate "none" is probably appropriate. If it returns null when it detects an error, then you are moving the error detection to the client code, which is kinda silly. Theres probably lots of "client" code for the library - and this means you are duplicating a bunch of code. It also means you have created some pretty close coupling as well. Whatever you do, make sure its clearly documented.
Mark Churchill Director, Dunn & Churchill Pty Ltd Free Download: Diamond Binding: The simple, powerful, reliable, and effective data layer toolkit for Visual Studio.
Entanglar: .Net game engine featuring automatic networking and powerful HLSL gfx binding.