Forneça uma maneira estritamente digitada de lidar com os resultados de sucesso e erros para seus aplicativos PHP.
Inspirado por Neverhrow, então aqui estamos com uma simples implementação de nunca em php.
Jogar e capturar é muito semelhante ao uso de declarações Goto - em outras palavras; Isso dificulta o raciocínio sobre seus programas. Em segundo lugar, usando o Throw, você pressupõe que o chamador de sua função está implementando a captura. Esta é uma fonte conhecida de erros. Exemplo: um dev joga e outro dev usa a função sem conhecimento prévio de que a função será lançada. Assim, e o caso de borda foi deixado sem conhecimento e agora você tem usuários infelizes, chefes, gatos, etc.
Com tudo isso dito, definitivamente existem bons casos de uso para jogar seu programa. Mas muito menos do que você imagina.
Tl; dr: não é arremesso = vida e aplicação mais felizes. Menos erros na produção e aumentam as coisas secas e reutilizáveis em seus aplicativos PHP.
Php 8.2+ desde v2.0.0
composer require shipsaas/never-throw A classe NeverThrow\Result foi estendida a qualquer momento.
isOk()isError()getOkResult()getErrorResult() Criaremos duas novas classes: sucesso e erro. E fique à vontade para colocar qualquer um de seus dados
use NeverThrow SuccessResult ;
use NeverThrow ErrorResult ;
// Success
class BookShipperOkResult extends SuccessResult
{
public function __construct (
public string $ bookingId
) {}
}
enum BookingErrors {
case NO_SHIPPER_AVAILABLE ;
case OVERWEIGHT_PACKAGE ;
case INVALID_ADDRESS ;
}
// Error
class BookShipperErrorResult extends ErrorResult
{
public function __construct (
public BookingErrors $ outcome
) {}
}Última etapa antes de usar o Neverhrow. Criar uma aula de resultado dedicada nos ajuda a:
use NeverThrow Result ;
class BookShipperResult extends Result
{
public function getOkResult (): BookShipperOkResult
{
return parent :: getOkResult ();
}
public function getErrorResult (): BookShipperErrorResult
{
return parent :: getErrorResult ();
}
} public function createBooking ( User $ user , BookingOrder $ order ): BookShipperResult
{
$ hasAnyShipperAvailable = $ this -> shipperService -> hasAnyShipperAvailable ();
if (! $ hasAnyShipperAvailable ) {
return new BookShipperResult (
new BookShipperErrorResult (
BookingErrors:: NO_SHIPPER_AVAILABLE
)
);
}
$ isOverweight = ! $ this -> weightService -> isValid ( $ order );
if ( $ isOverweight ) {
return new BookShipperResult (
new BookShipperErrorResult (
BookingErrors:: OVERWEIGHT_PACKAGE
)
);
}
$ bookingId = $ this -> book ( $ user , $ order );
return new BookShipperResult ( new BookShipperOkResult ( $ bookingId ));
} $ bookingResult = $ this -> service -> createBooking ( $ user , $ order );
if ( $ bookingResult -> isError ()) {
$ errorResult = $ bookingResult -> getErrorResult ();
// handle error
return showError ( match ( $ errorResult -> outcome ) {
BookingErrors:: NO_SHIPPER_AVAILABLE => ' No shipper available at the moment. Please wait ' ,
BookingErrors:: OVERWEIGHT_PACKAGE => ' Your package is overweight ' ,
});
}
return showBooking ( $ bookingResult -> getOkResult ()-> bookingId );Como você pode ver com o código acima, existem:
Isso traria o desenvolvimento realmente incrível e sem dor.
Com tipos de retorno estritamente digitado, os desenvolvedores podem saber o que está acontecendo com outros serviços/bibliotecas. Assim torna o reutilizável melhor. E não precisamos embrulhar a tentativa/captura e animar nosso código.
Não abusar de exceções, elas devem ser usadas apenas para as situações inesperadas (e erros! == Exceções, fato).
function transfer (): Transaction
{
if (! $ hasEnoughBalance ) {
thrown new InsufficientBalanceError ();
}
if (! $ invalidRecipient ) {
throw new InvalidRecipientError ();
}
if (! $ invalidMoney ) {
throw new InvalidTransferMoneyError ();
}
$ transaction = $ this -> transferService -> transfer (...);
if (! $ transaction ) {
throw new TransferFailedError ();
}
return $ transaction ;
}A maior parte dessa função é realmente sobre as coisas que podem dar errado, mas nossos tipos apenas nos informam do caminho de sucesso. Isso significa que 4/5ths da saída da função não são criados !
As "exceções" ou "erros" acima não são realmente exceções ou erros. Eles são resultados. Eles são partes previsíveis e razoáveis do nosso sistema. Minha heurística é que, se eles são algo que um bom gerente de produto se importaria, não são exceções e você não deve jogá -los!
Exceções são coisas imprevisíveis para as quais não podemos planejar razoavelmente, de que o sistema não deve tentar a recuperação e não devemos andar para o usuário.
MIT Licença