Huuum... vamos ver.
De fato precisa informar o usuário o que está acontecendo. Não tem que dar detalhes, não tem que encher ele de informação que ele não vai ler e vai clicar em qualquer coisa para sumir aquilo, e não pode vazar informação que pode prejudicar a segurança. Embora em frontend web meio que tanto faz, é tudo inseguro mesmo, se você mandar informação que não deve não é a exceão que vai atrapalhar.
Mas aqui começo falar que não é questão de exceção, é de ter um indicador de erro. Erro recuperável tem que informar o usuário e pedir para ele ajudar a resulver. Erro irrecuperável você informa que fez merda e não deixa piorar. Não deve fazer outras coisa, a não ser que faça muito sentido (não é fácil).
Fora falha de design geral, só tem esses dois tipos de erro, falha pontual de acordo com a infra, da comunicação ou entrada de dados (recuperável) ou erro do programador ou falha generalizada de ambiente (irrecupaerável). Não tente recuperar o irrecuperável. Pode só logar e tentar terminar sem ficar feio. Depois arruma o erro.
Vou passar bem rápido, quando se usa linguagens de script está pedinndo para dar problema na cara do usuário. Precisa testar absurdamente mais que um linguagem mais robusta. Isso deveria pesar muito na escolha, mas as pessoas não fazem assim, elas preferem coisas mais subjetivas para decidir.
Ter ferremantas que ajudam o usuário é correlato, não é o erro/exceção. parte disso foi falado aí.
É claro que achar a mensagem certa é importante. Mas o que eu queria dizer é que potencialmente isso nada tem a ver com exceção. UX do usuário final não costuma ser bom mostrar a exceção. para o programador também pode ser não seja melhor mostrar só a exceção (depende).
Na verdade aqui vou entrar na minha parte favorita: jogar pedra na exceção :D. Uma pena que algumas linguagens criaram isso errado nos anos 90 e um pouco mais, e que bom que as mais modernas abandonaram iso. Pena que algumas culturas abusam de exceções, outras nem tanto. Eu até ach oque deve seguir a cultura vigente. Mas entende oque é mais certo e o que não é. Eu não vou entrar em todos os detalhes aqui.
Exceção é para algo excepcional. O ideal seria só erro irrecuperável (que você nem tanta recuperar, o que é um erro comum que fazem por aí). Em algumas tecnologias faz sentido ter exceções para erros recuperáveis que não deveriam ocorrer, mas você não tem controle, ou seja, não deixam de ser excepcionais. Em tecnologias mais novas até esses erros nãoaõ são considerados excepcionais.
Quando algo é esperado, se a entrada de dados está errada, se pode acontecer algo, aquilo não é exceção. E é um erro conceitual alguém tentar fazer assim. Funciona, mas não é bom.
Exceção é um mecanismo todo errado é deveria ser abolido ou minimizado. Como não dá em certos cenários, devemos usar com mais cuidado e ter estratégias certas. Você pode fazer tudo que a exceção entrega sem ela, só será de um jeito diferente. E o maior problema é que tentaram fazer o mecanismo atender necessidades diferentes.
O correto é ter um mecanismo usando result pattern (recuperável) e um mecanismo de fail fast (até poderia ser uma exceção que não deve ser capturada, mas ser usada só para isto).
Curiosamente que as API do OS ou da web não usam exceções :D E como não quase tudo é falha pontual usam result pattern.
No Brasil há mais gosto por exceção por causa de alguns influenciadores. Algumas técnicas adotadas por modinha pregam mais exceção, mais um motivo para não gostar delas.
Faça o que sua equipe faz, o que sua tecnologia tem cultura de fazer. Mas aprenda que não é certo.
Vou falar mais disso daqui um tempo em blog/canal.
Claro não importa o que faça, precisa dar boas mensagens para o usuário final ou o programador.
Observou? Faz sentido para você?
Espero ter ajudado. Em geral estou à disposição na plataforma (sem abusos :D)
Farei algo que muitos pedem para aprender a programar corretamente, gratuitamente. Para saber quando, me segue nas suas plataformas preferidas. Quase não as uso, não terá infindas notificações (links aqui).