2017-09-22 1 views
1

J'ai ce code (très similaire à what is suggested here) qui lance une exception:Comment utiliser les codes d'erreur génériques enum avec les codes d'erreur system_category de <system_error>?

int accept4(int sockfd, sockaddr *addr, socklen_t *addrlen, int flags) 
{ 
    const int fd = ::accept4(sockfd, addr, addrlen, flags); 
    if (fd < 0) 
    { 
     const auto tmp = errno; 
     throw ::std::system_error(tmp, ::std::system_category(), "accept4(2)"); 
    } 
    else 
    { 
     return fd; 
    } 
} 

Et ce code pour le test pour une raison particulière d'exception:

catch (const ::std::system_error &e) 
{ 
    static const auto block_err = ::std::system_error(EWOULDBLOCK, 
                ::std::system_category()); 

    const auto ecode = e.code(); 

    // EWOULBLOCK is fine, everything else, re-throw it. 
    if (block_err.code() != ecode) 
    { 
     throw; 
    } 
} 

Cela semble un peu inutilement bavard et non tout à fait la bonne façon de faire les choses. Il y a toute cette idée d'erreurs génériques et une énumération complète (voir ::std::errc) avec une sorte de système censé convertir entre les codes d'erreur spécifiques au système et ces erreurs génériques. Je veux utiliser les codes d'erreur génériques et les catégories, et je n'arrive pas à les faire fonctionner. Comment puis-je faire ce travail?

Répondre

1

Sur une mise en œuvre de la qualité * suffisamment élevée, il suffit de faire

if (e.code() != std::errc::operation_would_block) 
    throw; 

Sinon, vous êtes coincé avec

if (e.code() != std::error_code(EWOULDBLOCK, std::system_category())) 
    throw; 

Il n'y a certainement pas besoin de construire un autre system_error juste pour le code d'erreur à l'intérieur.


* Il faut mettre en œuvre l » default_error_conditionsystem_category() pour cartographier de façon appropriée l'erreur à generic_category().