Estou trabalhando em uma grade que faz uso de um tipo Error definido em uma biblioteca de dependências, que utilizo como tipo de retorno de um método que precisa ser executado como parte de uma transação , como por exemplo:
use my_lib::Error;
fn foo() -> Result<(), Error>;
conn.transaction(|| { foo() });
Isso resulta no seguinte erro ao compilar:
error[E0277]: o atributo vinculado
my_lib::Error: std::convert::From<diesel::result::Error>
não está satisfeito
AFAIK não é possível para mim criar a implementação From<Error>
exigida por este método, porque o tipo my_lib::Error
está definido em outro engradado. E eu tenho que criar meu próprio tipo fictício TransactionError
apenas para mapear o my_lib::Error
(e mapeá-lo de volta no final da transação).
Existe uma forte razão para ter esta Característica ligada no lugar?
Seria possível removê-lo e tornar a API mais flexível?
Faça sugestões concretas de como uma API mais flexível ficaria se removêssemos esse limite. Lembre-se também de que todos os casos de uso com suporte hoje devem ter suporte no futuro, o que inclui o uso de um tipo de erro personalizado como tipo de retorno do retorno de chamada da transação.
Estou encerrando este problema agora, porque atualmente não é acionável para a equipe de diesel. Se você tiver alguma sugestão concreta, podemos falar sobre a reabertura desta edição.
Não conhecia esta política em Diesel
(esta foi a primeira edição que abri); na verdade, vejo muitos tickets abertos que não são acionáveis hoje, mas ainda estão abertos, por exemplo https://github.com/diesel-rs/diesel/issues/2084 , que por acaso me redirecionou para este comentário, que poderia ser aplicado aqui também https://github.com/diesel-rs/diesel/issues/399#issuecomment -603491154. Vou reabrir esta questão caso encontre tempo para pensar em uma alternativa, e deixo para você o trabalho de redirecionar outras pessoas que abrem questões semelhantes a esta fechada.
Eu provavelmente deveria explicar por que encerrei esta questão com um pouco mais de detalhes.
O código correspondente para a função de transação está aqui , para mostrar do que estamos falando. Temos as seguintes restrições lá:
Isso nos deixa no meu ponto de vista com exatamente duas opções:
From<diesel::result::Error>
vinculado lá.std::error::Error
ou algo assim.Isso significa que, no final, ambas as soluções exigiriam uma característica vinculada ao tipo de erro fornecido pelo usuário. Portanto, no caso geral, nenhuma dessas soluções resolverá seu problema.
na verdade, vejo muitos tickets abertos que não são acionáveis hoje, mas ainda estão abertos, por exemplo #2084,
Considero esse problema como acionável, consulte #2257.
Vou reabrir esta questão caso encontre tempo para pensar em uma alternativa, e deixo para você o trabalho de redirecionar outras pessoas que abrem questões semelhantes a esta fechada.
Para deixar claro novamente: Fechar um problema não significa que a discussão aqui está encerrada, apenas que não vejo o que poderia ser feito imediatamente para resolver o problema. Basicamente, todas as questões em aberto devem conter algo que um colaborador em potencial possa pegar e trabalhar. (Eu sei que não é necessariamente o caso de algum problema mais antigo)
Como uma possível solução alternativa para seu problema concreto: você pode simplesmente fazer seu próprio tipo de erro que envolve diesel::result::Error
e o tipo de erro de terceiros em um tipo comum. Então algo como
enum MyError<E> {
DieselError(diesel::result::Error),
LibraryError(E)
}
impl<E> From<diesel::result::Error> for MyError<E> {
fn from(e: diesel::result::Error) -> Self {
MyError::DieselError(e)
}
}
Comentários muito úteis
Eu provavelmente deveria explicar por que encerrei esta questão com um pouco mais de detalhes.
O código correspondente para a função de transação está aqui , para mostrar do que estamos falando. Temos as seguintes restrições lá:
Isso nos deixa no meu ponto de vista com exatamente duas opções:
From<diesel::result::Error>
vinculado lá.std::error::Error
ou algo assim.Isso significa que, no final, ambas as soluções exigiriam uma característica vinculada ao tipo de erro fornecido pelo usuário. Portanto, no caso geral, nenhuma dessas soluções resolverá seu problema.
Considero esse problema como acionável, consulte #2257.
Para deixar claro novamente: Fechar um problema não significa que a discussão aqui está encerrada, apenas que não vejo o que poderia ser feito imediatamente para resolver o problema. Basicamente, todas as questões em aberto devem conter algo que um colaborador em potencial possa pegar e trabalhar. (Eu sei que não é necessariamente o caso de algum problema mais antigo)
Como uma possível solução alternativa para seu problema concreto: você pode simplesmente fazer seu próprio tipo de erro que envolve
diesel::result::Error
e o tipo de erro de terceiros em um tipo comum. Então algo como