Práticas recomendadas de tratamento de exceções
Se uma exceção não for gravada no arquivo exception.log
com o modelo de exceção como contexto, ela não será reconhecida e analisada corretamente no New Relic ou em outro armazenamento de log compatível com monólogo PSR-3. Registrar somente uma parte da exceção (ou registrá-la no arquivo errado) gera bugs na produção quando as exceções são ignoradas.
Manuseio de exceção correto
A lista de verificação a seguir fornece exemplos para demonstrar o manuseio correto de exceções.
Gravar no log de exceções
Grave no log de exceções usando o seguinte padrão, independentemente de outras ações, a menos que haja um motivo convincente para não fazê-lo.
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->critical($e);
}
Esta abordagem salva automaticamente o $e->getMessage
na mensagem de log e o objeto $e
no contexto, seguindo o padrão de contexto PSR-3. Isso é feito em \Magento\Framework\Logger\Monolog::addRecord
.
Sinais mudos
Silencie sinais ao não registrar exceções que fazem parte do fluxo de operações pretendido. Nenhuma ação de acompanhamento é necessária quando a exceção é encontrada, portanto, ela não precisa ser registrada e analisada quando ocorrer. Adicione um comentário indicando o motivo para silenciar sinais e que é intencional. Combinar com phpcs:ignore
.
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) { // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch
// Product already removed
}
exceções de downgrade
Faça downgrade das exceções seguindo o padrão de contexto PSR-3.
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->debug($e->getMessage(), ['exception' => $e]);
}
O registro sempre vem primeiro
Como prática recomendada, o registro em log sempre vem primeiro no código para evitar casos em que outra exceção ou erro fatal é lançado antes da gravação no log.
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->critical($e);
$this->alternativeProcedure();
}
Mensagens de log e todo o rastreamento de exceção
Registre mensagens e todo o rastreamento de exceção seguindo o padrão de contexto PSR-3.
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->critical($e->getMessage(), ['exception' => $e, 'trace' => $e->getTrace()]);
}
Tratamento de exceção incorreto
Os exemplos a seguir demonstram o tratamento incorreto de exceções.
Lógica antes de fazer logon
A lógica antes do registro em log pode levar a outra exceção ou erro fatal, que impede que a exceção seja registrada e deve ser substituída por exemplo correto.
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) {
$this->alternativeProcedure();
$this->logger->critical($e);
}
Vazio catch
Blocos catch
vazios podem ser sinal de silenciamento não intencional e devem ser substituídos pelo exemplo correto.
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) {
}
Localização dupla
Se a exceção localizada capturada ainda não for traduzida, resolva o problema no local em que a exceção é gerada pela primeira vez.
try {
$this->productRepository->getById($sku);
} catch (LocalizedException $e) {
throw new LocalizedException(__($e->getMessage()));
}
Registra mensagens e rastreia para diferentes arquivos de registro
O código a seguir registra incorretamente o rastreamento de pilha de uma exceção como uma string em um arquivo de log.
try {
$this->productRepository->getById($sku);
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
$this->logger->debug($e->getTraceAsString());
}
Essa abordagem introduz quebras de linha na mensagem, que não é compatível com o PSR-3. A exceção, incluindo o rastreamento de pilha, deve fazer parte do contexto da mensagem para garantir que ela seja salva corretamente com a mensagem no New Relic ou em outro armazenamento de log compatível com monólogo PSR-3.
Corrija esse problema substituindo o código seguindo os exemplos corretos mostrados em Gravar no log de exceções ou Baixar exceções.
. Rebaixar exceções sem contexto
A exceção foi rebaixada para um erro, que não permite que um objeto seja passado, mas apenas uma cadeia de caracteres, portanto o getMessage()
. Isso faz com que o rastreamento seja perdido e deve ser substituído pelos exemplos corretos mostrados em Gravar no log de exceções ou Baixar exceções.
try {
$this->productRepository->getById($sku);
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
}
registra somente a mensagem no log de exceção
Em vez de passar o objeto $e
, apenas $e->getMessage()
é passado. Isso faz com que o rastreamento seja perdido e deve ser substituído pelos exemplos corretos mostrados Gravar no log de exceções ou Baixar exceções.
try {
$this->productRepository->getById($sku);
} catch (\Exception $e) {
$this->logger->critical($e->getMessage());
}
// phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch
ausente(s)
A omissão da linha phpcs:ignore
aciona um aviso no PHPCS e não deve passar seu CI. Este deve ser substituído pelo exemplo correto mostrado em Sinais mudos.
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) {
// Product already removed
}