Magento CLI 2.4.0 - ErrorHandler PHP त्रुटियों को उत्पादन मोड में अपवादों में बदल रहा है
प्रस्तावना: मैं डेवलपर मोड में विकसित करना पसंद करता हूं, मैगेंटो को सभी PHP E_NOTICE|E_WARNING|etc.त्रुटियों को पकड़ना , उन पर अपवाद फेंकना और मेरे कोड करने से पहले इन मुद्दों को साफ करना चाहिए। हालाँकि समस्या तीसरे पक्ष के विस्तार में रहती है, और मैं उनकी समस्या को रिपोर्ट करना चाहता हूँ।
मुसीबत:
जैसा कि शीर्षक में कहा गया है, Magento अभी भी Magento\Framework\App\ErrorHandler::handlerउत्पादन मोड में रहते हुए PHP स्तर की त्रुटियों को अपवादों में परिवर्तित कर रहा है। मेरे वर्तमान विकास प्रयासों के हिस्से के रूप में, मुझे तीसरे पक्ष के विस्तार पर निर्भर रहना पड़ रहा है, और उनके पास एक तार्किक बग है जो निम्न E_NOTICEत्रुटि त्रुटि पैदा कर रहा है Notice: Trying to access array offset on value of type null in /path/to/project/vendor/magento/module-catalog-import-export/Model/Import/Product.php on line 1281:।
किसी को भी कोड के इस विशेष क्षेत्र से परिचित है, राज्य के लिए मजबूर महसूस कर सकते हैं कि बग जरूरतों ऊपर या पंक्ति के पर डेटा की कमी की वजह से साफ करने के लिए किसी और उत्पादों के आयात नहीं होगा काम type_idऔर _attribute_set। कृपया जान लें कि यह मामला नहीं है, जैसा कि तीसरे पक्ष के विस्तार में है, तीसरे पक्ष के मॉड्यूल डीबी में वास्तविक आयात से पहले इन महत्वपूर्ण कुंजियों को ठीक से सेट करेंगे।
वापस मेरे मुद्दे पर वापस: तीसरे पक्ष के विस्तार में इस समस्या के कारण, मैं डेवलपर मोड में रहते हुए स्थानीय रूप से पूरा होने के लिए चल रहे आयात का परीक्षण करने में असमर्थ हूं, क्योंकि (उम्मीद के मुताबिक) Magento इस PHP E_NOTICE स्तर की त्रुटि को एक अपवाद में बदल देगा। जिससे आयात विफल हो गया। इसलिए, स्थानीय रूप से, मैंने Magento को उत्पादन मोड में बदलने का फैसला किया है ताकि इन PHP त्रुटियों को अपवाद में परिवर्तित होने से रोका जा सके। दुर्भाग्य से यह समस्या हल करने के लिए नहीं लगता है, और ErrorHandlerइस समस्या के लिए अपवादों को फेंकना जारी है जबकि मैगनेटो उत्पादन मोड में है।
मैंने Magento के कोड पर करीब से नज़र डालने का फैसला किया है, और मैं खुद यह निर्धारित नहीं कर सकता कि कैसे (उत्पादन मोड) Magento का मानना है कि PHP त्रुटियों के लिए अपवादों को पहली जगह पर फेंकने से बचें। कोड के माध्यम से कदम मैं देख सकता हूँ कि:
bin/magentoनिष्पादन का प्रवेश बिंदु होगा, क्योंकि मैं सीएलआई से आयात चला रहा हूंbin/magentoपर एक शामिल प्रदर्शन करेंगेapp/bootstrap.phpbootstrap.phpतुरंत PHP की त्रुटि रिपोर्टिंग स्तर को सेट करता हैE_ALLbin/magentoPHP के त्रुटि हैंडलर को सेट करने के लिए आय\Magento\Framework\App\ErrorHandlerbin/magentoएक सिम्फनी कंसोल एप्लिकेशन बनाता है और चलाता है।
क्योंकि app/bootstrap.phpत्रुटि रिपोर्टिंग स्तर सेट करता है E_ALL, भले ही वर्तमान रिपोर्टिंग स्तर क्या हो, मैं केवल यह मान सकता हूं कि निष्पादन स्टैक मैगनेटो के साथ कहीं न कहीं वर्तमान एप्लिकेशन मोड से परामर्श करना होगा। यदि "उत्पादन" के रूप में चल रहा है, error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING ...)तो इस तरह की त्रुटियों के लिए अपवाद को फेंकने से उत्पादन मोड को रोकने के लिए कुछ की तर्ज पर प्रदर्शन करें । हालाँकि कहीं भी मुझे इस तरह के तर्क का पता नहीं चल पाया है। इसलिए मैं नुकसान में हूं कि कैसे उत्पादन मोड आम तौर पर ErrorHandlerइन PHP त्रुटियों को अपवाद में बदलने से रोकता है।
यदि मैं सीधे ErrorHandler.phpसशर्त, जो झूठा वापस आता है, को जोड़ने से पहले संशोधित करता है:
echo "errNo: $errorNo\nerror_reporting: ". error_reporting() . "\nbitwise result: " . ($errorNo & error_reporting()) . "\nE_ALL: " . E_ALL . "\n";
मुझे कंसोल में निम्नलिखित आउटपुट मिलते हैं:
errNo: 8
error_reporting: 32767
bitwise result: 8
E_ALL: 32767
इसलिए return false;कभी भी मुलाकात नहीं की जाती है, और कोड E_NOTICEत्रुटि को एक अपवाद में बदल देता है। यदि इस पंक्ति से पहले सीधे: $errorNo = $errorNo & error_reporting();मैं निम्नलिखित जोड़ता हूं: error_reporting(E_ALL & ~E_NOTICE);त्रुटि हैंडलर उम्मीद के मुताबिक गलत वापस आ जाएगा। जाहिर है कि यह कोई समाधान नहीं है, लेकिन अपने वर्तमान कार्य पर प्रगति जारी रखने के लिए मैंने अब अस्थायी रूप से सहारा लिया है।
ध्यान देने योग्य कुछ अतिरिक्त बातें:
- मैंने PHP बाइनरी को पास करने की कोशिश की है
-d display_errors=0, जो कोई प्रभाव नहीं देता है (जैसा कि PHP अभी भी त्रुटियों की रिपोर्ट करेगाerror_log) - मैंने PHP बाइनरी को पास करने की कोशिश की है
-d log_errors=0, जो कोई प्रभाव नहीं देता है - मैंने PHP बाइनरी को पास करने की कोशिश की है
-d error_reporting=0, जो स्पष्ट रूप से मैगेंटो केbootstrap.phpइसे बदलने के कारण कोई प्रभाव नहीं देता हैE_ALL। - मैंने उपरोक्त सभी को व्यक्तिगत रूप से, साथ ही साथ एक बार आजमाया है।
- मेरे पास कैश फ्लश है, साथ ही अक्षम कैश, साथ ही उड़ा दिया गया है
var/cacheऔरgenerated/code - मैंने अपना पूरा एप्लिकेशन उड़ा दिया है (
app/etc/env.phpपहले बैकअप कर रहा हूं ), HEAD से हार्ड रीसेट करने के लिए आगे बढ़ा ,composer installनए सिरे से आश्रितों को लाने के लिए निष्पादित किया, ताकि कुछ भी मिटा दिया जाए जो मुझे याद आ गया है जो कैश हो गया है, जो कोई प्रभाव नहीं देता (पुनर्स्थापितenv.phpऔर पुनः -कंपनी उत्पादन मोड) - कैशे को वर्तमान में मैगेंटो की
var/cacheनिर्देशिका के तहत बॉक्स फाइल सिस्टम कैश से बाहर कॉन्फ़िगर किया गया है
पिछले कुछ नोट:
- अधिकांश भाग के लिए यह अभी भी Magento 2.4.0 के बॉक्स इंस्टॉलेशन से बाहर है। इसमें किए गए अनुकूलन के संदर्भ में बहुत कम है, निश्चित रूप
error_reporting()से अपने आप (या अन्य देवों द्वारा स्तर के किसी भी संशोधन नहीं , क्योंकि मैं इस बिंदु पर कोड को छूने वाला एकमात्र देव हूं)। - तीसरे पक्ष का विस्तार
firebear/importexportसंस्करण है3.4.3। इस एक्सटेंशन की समीक्षा से पता नहीं चलता है कि यहerror_reporting()स्तर बदल रहा है या तो। - php संस्करण: 7.4.9
TL; DR: मुझे नहीं पता कि Magento उत्पादन मोड में ErrorHandlerमामूली PHP त्रुटियों के लिए अपवादों को फेंकने की अनुमति क्यों जारी है ।
EDIT 2020.10.07
FactoryAidan के उत्तर का उत्तर: (मूल प्रश्न को कवर नहीं करता है, लेकिन बताता है कि E_NOTICE स्तर की त्रुटि पहले स्थान पर क्यों होती है)
यह मेरी व्यक्तिगत राय है कि E_NOTICE स्तर की त्रुटि की घटना मुख्य रूप से Firebear_ImportExport में तर्क बग के कारण होती है, जैसा कि मुख्य Magento कोड में तार्किक बग के विपरीत है। मुझे इसके बाद पुन: उपसर्ग करने दें कि मैं आपके कथन से सहमत हूं "मैगेंटो कोर कोड की जाँच की गई थी यदि nullइसे वापस कर दिया गया था $this->skuProcessor->getNewSku($lastSku), तो फायरबियर के एक्सटेंशन का उपयोग करते समय यह पहली समस्या नहीं होगी।
अब, मेरे तर्क के अनुसार, मैं अभी भी इसके लिए फायरबियर पर उंगली क्यों इंगित करता हूं (इसमें मैगेंटो के प्रति कुछ आलोचना भी शामिल होगी, लेकिन यहां मुख्य समस्या फायरबियर के साथ है कि मैगेंटो ने जो किया है उसका पालन नहीं किया जाता है)।
Magento 2.4.0 में, यदि हम \Magento\CatalogImportExport\Model\Import\Product2481- 2488 की पंक्तियों को देखते हैं, तो हम निम्नलिखित पाएंगे:
if ($this->isSkuExist($sku) && Import::BEHAVIOR_REPLACE !== $this->getBehavior()) { // can we get all necessary data from existent DB product? check for supported type of existing product if (isset($this->_productTypeModels[$this->getExistingSku($sku)['type_id']])) {
$this->skuProcessor->addNewSku( $sku,
$this->prepareNewSkuData($sku)
);
इस तर्क को सत्यापित करते हुए, हम देख सकते हैं कि कोड निम्नलिखित कर रहा है (गैर महत्वपूर्ण पहलुओं को छोड़कर):
- अगर स्कू पहले से मौजूद है
- यदि मौजूदा स्कू
type_idमान्य है - फिर इस मौजूदा स्कू को नई स्कस के SkuProcessor के अरै में जोड़ें ।
-- रुको क्या? जोड़ने के मौजूदा करने के लिए नई SKUs सरणी? यह नया क्यों नहीं है, हमने सचमुच पुष्टि की कि यह पहले से मौजूद है। (यह वह जगह है जहाँ मेरी Magento की आलोचना है।
यहां बताए गए तरीकों के माध्यम से उठाते हुए, हम अनिवार्य रूप से इस निष्कर्ष पर आते हैं कि: "मैगेंटो यह सुनिश्चित कर रहा है कि मौजूदा स्कोस को अपडेट करते समय, हमें " type_idऔर attribute_set_id" को संशोधित करने की अनुमति नहीं है । मैगेंटो एक अजीब तरीके से इसके बारे में जाता है, जो \Magento\CatalogImportExport\Model\Import\Product::_prepareNewSkuData()एक सरणी बनाने के लिए झुकता है जिसमें मौजूदा type_idऔर attr_set_codeमान हैं, इस सरणी को SkuProcessor में "नया sku" के रूप में पारित करना है, इसके बावजूद कि यह वास्तव में एक मौजूदा डेटा है।
फिर, इन शेंनिगन्स के माध्यम से, मैगेंटो ने अब खुद को हमेशा विशेष रूप से सेट करने के लिए छलावा किया है type_idऔर मौजूदा समय के attr_set_codeदौरान \Magento\CatalogImportExport\Model\Import\Product::_prepareRowForDb()विधि के भीतर ।
Firebear के लिए के रूप में? उन्होंने मौजूदा उत्पादों पर \ Magento \ CatalogImportExport \ Model \ Import \ Product , and these lines 2481-2488 of the original model don't ever execute. Firebear (intentionally, per their documentation on their website) allows for changing of both type_id andattr_set_code ' ओवरराइड किया है। जो, मेरी राय में, ठीक है। हालाँकि, जब कोई उत्पाद प्रारंभिक सत्यापन पास कर लेता है, तो वे ऐसा करने के लिए उपेक्षा करते हैं "मौजूदा स्कू डेटा को जोड़ने के लिए, नए स्केस की सरणी में", और यही कारण है कि E_NOTICE स्तर की त्रुटि अब होती है।
शायद वे जानबूझकर ऐसा नहीं करते हैं, ताकि type_idऔर attr_set_codeदेशी द्वारा "रीसेट" नहीं हैं _prepareRowForDb()विधि। हालाँकि, अगर यह मामला है, तो उनके लिए यह वास्तव में सरल होगा कि वे मूल _prepareRowForDbविधि को कॉल करें , और बाद में आयात से प्रदान किए गए डेटा के साथ इन दो सरणी कुंजी मानों को सेट करें।
अंत में, मेरा समाधान Model\Import\Productएक बार फिर से क्लास लेना था , फायरबियर का विस्तार करना, जो मैगेंटो का विस्तार करता है। यहाँ मैं त्रुटि रिपोर्टिंग स्तर parent::_prepareRowForDb()को सेट करने से पहले त्रुटि रिपोर्टिंग स्तर को संशोधित करता हूं, बाद में इसका मूल मूल्य।
मेरा स्रोत कोड:
/***
* E_NOTICE level error is breaking import on updates of existing products
* because \Magento\Framework\App\ErrorHandler is catching the error
* and converting it into an exception.
*
* This error is occurring due to a logical bug in firebear/importexport
*
* Native magento/module-catalog-import-export will invoke
* \Magento\CatalogImportExport\Model\Import\Product\SkuProcessor::addNewSku()
* for rows that have passed validation, when the import behavior update.
*
* firebear/importexport does not, and so the SkuProcessor returns
* null to \Magento\CatalogImportExport\Model\Import\Product::_prepareRowForDb()
* when updating existing SKUs. Immediately afterwards, this error occurs:
*
* Notice: Trying to access array offset on value of type null in
* vendor/magento/module-catalog-import-export/Model/Import/Product.php on line 1281
*
* Combinations of package versions that first discovered to yield this logic error:
* Magento Open Source 2.4.0
* firebear/importexport: 3.4.3
* magento/module-catalog-import-export: 101.1.0
*
* {@inheritDoc}
* @see \Firebear\ImportExport\Model\Import\Product::_prepareRowForDb()
* phpcs:disable PSR2.Methods.MethodDeclaration.Underscore
*/
protected function _prepareRowForDb(array $rowData): array { $level = error_reporting();
if (E_NOTICE & $level === 0) { return parent::_prepareRowForDb($rowData);
}
error_reporting($level & ~E_NOTICE); $rowData = parent::_prepareRowForDb($rowData); error_reporting($level);
return $rowData;
}
जवाब
🔥 मैं Magento 2.4.0 और फायरबियर का भी उपयोग कर रहा हूं।
⚠️ यह एक Magento कोर बग का परिणाम है:
vendor/magento/module-catalog-import-export/Model/Import/Product.php::_prepareRowForDb
कहाँ पे:
- लाइन 1280: का
$this->skuProcessor->getNewSku($lastSku)रिटर्न प्रकार हो सकता है,array|nullलेकिनnullसंभाला नहीं है।
Installation .patchअपने मौजूदा इंस्टॉलेशन पर निम्न फ़ाइल का उपयोग करें जो बग्ड कोर मॉड्यूल को अपडेट करेगा:
- M2.4.0 पैच दोनों सरणी को संभालने के लिए | अशक्त वापसी प्रकार getNewSku()
के साथ पैच को स्थापित करने के लिए composer.json, जिस्ट लिंक्ड, में पहली टिप्पणी देखें।
ento यह समाधान मैजेंटो एंटरप्राइज क्लाउड एडिशन वातावरण में सफलतापूर्वक समाप्त हो गया है।