In the first place, a class or library is created when you do not want to worry about the details of an implementation, but then you need to know the inner workings of the class to properly handle the exceptions it might throw.
Doesn’t this break the principle of encapsulation and information hiding ? Or I am totally wrong on this ?
Sure I can have a generic try/catch block to intercept all exceptions, but that is definitely a bad practice.
So how can I come up with good exception handling strategy without knowing the details of each exceptions that might be thrown ?
A well-designed class or library will document what exceptions it throws as part of the interface, perhaps even going so far as to define its own hierarchy of exception classes. For instance, a foo subclass class might throw a “foo persistence exception” if the disk is full, and another subclass would throw one if the network is down. As the caller, you would catch a foo persistence exception because your concern is that data was not persisted. You shouldn’t be expected to write code specifically for disk full, network down, disk not present, disk write error, subspace transceiver interference, &c.
It may be the case that you can’t do much about many of them.