The need to have an exception object is for the help of consumers to the addon. Once it hits the console there is a stack trace, There is a clear error message that developers can understand. And as an object a developer can easily catch the error and choose to deal with it (i.e. offer a friendly not found message translated correctly).
As for the difference between reject vs throw these are exactly the same thing. There is no difference. If you throw inside a then it is the same thing as returning a rejected promise. The difference is semantic and seeing a throw is more clear to those who are reading the code then a reject which doesn't stand out and (for me) would require a larger level of cognitive load then a language keyword like throw.
Quote by @sukima in #78.