Is there a best practice for defining custom error types in a Ruby library (gem) or Ruby on Rails application? Specifically:

Where do they belong structurally in the project? A separate file, inlined with the relevant module/class definition, somewhere else?

Are there any conventions that establish when to and when not to create a new error type?

Different libraries have different ways of doing things, and I haven't noticed any real patterns. Some libraries always use custom error types while others don't use them at all; some have all errors extending StandardError while others have nested hierarchies; some are just empty class definitions, others have all sorts of clever tricks.

Oh, and just because I feel like calling these "error types" is sort of ambiguous, what I mean is this:

I think in order to have cohesive source files in your project, you should define errors in the class in which may throw them and nowhere else.

Some heirarchy can be helpful - namespaces are good at keeping redundant strings out of type names - but that's more a matter of taste - there's no need to go overboard provided you have at least one custom exception type in your app which you use throughout to differentiate between 'intentional' and 'accidental' exception cases.