Diesel: Remover traço vinculado de<error>da Conexão::transação</error>

Criado em 27 mar. 2020  ·  3Comentários  ·  Fonte: diesel-rs/diesel

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?

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á:

  • Precisamos retornar algum tipo de erro dessa função porque uma transação pode falhar
  • Um usuário em potencial deve ser capaz de fornecer retornos de chamada específicos do domínio, isso significa que eles podem retornar seu próprio tipo de erro
  • Precisamos ter alguma maneira de lidar com um erro interno (como a conexão foi perdida ou algo assim) enquanto fazemos o tratamento da transação.

Isso nos deixa no meu ponto de vista com exatamente duas opções:

  1. A maneira atual, dizendo que deve haver uma maneira de converter um erro de diesel para o tipo de erro fornecido pelo usuário. Como requisito, isso precisa do From<diesel::result::Error> vinculado lá.
  2. Envolvendo o tipo de erro fornecido pelo usuário de alguma forma em um tipo de erro fornecido pelo diesel. Isso também exigiria algum limite no tipo de erro fornecido pelo usuário para ser útil, provavelmente 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)
    }
}
  • agrupar o retorno de chamada para fazer uma transformação de erro adicional deve funcionar para você.

Todos 3 comentários

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á:

  • Precisamos retornar algum tipo de erro dessa função porque uma transação pode falhar
  • Um usuário em potencial deve ser capaz de fornecer retornos de chamada específicos do domínio, isso significa que eles podem retornar seu próprio tipo de erro
  • Precisamos ter alguma maneira de lidar com um erro interno (como a conexão foi perdida ou algo assim) enquanto fazemos o tratamento da transação.

Isso nos deixa no meu ponto de vista com exatamente duas opções:

  1. A maneira atual, dizendo que deve haver uma maneira de converter um erro de diesel para o tipo de erro fornecido pelo usuário. Como requisito, isso precisa do From<diesel::result::Error> vinculado lá.
  2. Envolvendo o tipo de erro fornecido pelo usuário de alguma forma em um tipo de erro fornecido pelo diesel. Isso também exigiria algum limite no tipo de erro fornecido pelo usuário para ser útil, provavelmente 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)
    }
}
  • agrupar o retorno de chamada para fazer uma transformação de erro adicional deve funcionar para você.
Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

jimmycuadra picture jimmycuadra  ·  4Comentários

Fuckoffee picture Fuckoffee  ·  3Comentários

ghost picture ghost  ·  3Comentários

pwoolcoc picture pwoolcoc  ·  3Comentários

pjenvey picture pjenvey  ·  4Comentários