例外狀況處理最佳實務
如果例外狀況未以例外狀況模型作為內容寫入exception.log
檔案,則無法在New Relic或其他PSR-3單一記錄檔相容記錄儲存體中正確識別及分析該例外狀況。 僅記錄例外狀況的一部分(或將其記錄到錯誤的檔案)會在忽略例外狀況時導致生產中的錯誤。
正確的例外狀況處理
下列檢查清單提供範例,示範如何正確處理例外狀況。
寫入例外狀況記錄檔
使用下列模式寫入例外記錄檔,不考慮進一步的動作,除非有令人信服的理由不這樣做。
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->critical($e);
}
此方法會依照PSR-3內容標準,自動將$e->getMessage
儲存至記錄訊息,並將$e
物件儲存至內容。 這已在\Magento\Framework\Logger\Monolog::addRecord
內完成。
靜音訊號
不記錄屬於預期作業流程一部分的例外狀況,將訊號設為靜音。 發生例外狀況時不需要進行後續動作,因此發生例外狀況時不需要記錄和分析。 新增註解,說明將訊號靜音的原因,以及這是刻意為之。 與phpcs:ignore
合併。
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) { // phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch
// Product already removed
}
降級例外狀況
依照PSR-3內容標準降級例外狀況。
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->debug($e->getMessage(), ['exception' => $e]);
}
永遠先進行記錄
最佳實務是永遠先在程式碼中記錄,以防止在寫入記錄檔之前擲回另一個例外狀況或嚴重錯誤的情況。
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->critical($e);
$this->alternativeProcedure();
}
記錄訊息和整個例外狀況追蹤
遵循PSR-3內容標準,以記錄訊息和整個例外狀況追蹤。
try {
$this->productRepository->getById($sku);
} catch (Exception $e) {
$this->logger->critical($e->getMessage(), ['exception' => $e, 'trace' => $e->getTrace()]);
}
不正確的例外狀況處理
下列範例示範不正確的例外狀況處理。
記錄前的邏輯可能會導致另一個例外狀況或嚴重錯誤,這會防止例外狀況被記錄,應該以正確的範例取代。
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) {
$this->alternativeProcedure();
$this->logger->critical($e);
}
空白catch
空的catch
區塊可能是非預期靜音的符號,應以正確的範例取代。
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) {
}
重複本地化
如果攔截到的當地語系化例外狀況尚未轉譯,請在第一次擲回例外狀況的位置解決問題。
try {
$this->productRepository->getById($sku);
} catch (LocalizedException $e) {
throw new LocalizedException(__($e->getMessage()));
}
記錄訊息及追蹤至不同的記錄檔
下列程式碼會將例外狀況的棧疊追蹤錯誤記錄為記錄檔的字串。
try {
$this->productRepository->getById($sku);
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
$this->logger->debug($e->getTraceAsString());
}
此方法在訊息中引入了分行符號,這與PSR-3不相容。 例外狀況(包括棧疊追蹤)必須屬於訊息內容的一部分,以確保其能正確與訊息一起儲存在New Relic或其他PSR-3單一記錄檔相容的記錄儲存體中。
請取代下列程式碼,以修正此問題: 寫入例外狀況記錄檔或降級例外狀況中所示的正確範例。
沒有內容的降級例外狀況
例外狀況會降級為錯誤,不允許傳遞物件,但只允許字串,因此getMessage()
。 這會導致追蹤遺失,應該以寫入例外狀況記錄檔或降級例外狀況中所示的正確範例取代。
try {
$this->productRepository->getById($sku);
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
}
僅將訊息記錄到例外狀況記錄檔
未傳遞物件$e
,僅傳遞$e->getMessage()
。 這會造成追蹤遺失,應該以正確範例取代,如寫入例外記錄檔或降級例外狀況所示。
try {
$this->productRepository->getById($sku);
} catch (\Exception $e) {
$this->logger->critical($e->getMessage());
}
遺失// phpcs:ignore Magento2.CodeAnalysis.EmptyBlock.DetectedCatch
省略phpcs:ignore
行會在PHPC中觸發警告,且不應傳遞您的CI。 應該以靜音訊號中顯示的正確範例來取代此專案。
try {
$this->productRepository->deleteById($sku);
} catch (NoSuchEntityException $e) {
// Product already removed
}