Eu recebi logs de exceção para esse erro na produção, mas não consigo reproduzir o problema no meu ambiente local ou intermediário, por isso tem sido muito difícil solucionar problemas.
O erro se origina Mage_Sales_Model_Service_Quote::_validate()
porque o $rate
retornado por $rate = $address->getShippingRateByCode($method)
está vazio.
Eu adicionei alguns logs para tentar ter uma idéia melhor do que estava acontecendo, e vejo que ele $method
contém o método de envio correto.
Meu melhor palpite é que, em algum momento do processo, as taxas de remessa sejam excluídas antes de quando deveriam ser.
Percebi que toda vez que essa exceção ocorre, ocorre imediatamente após uma exceção legítima, como um cartão de crédito inválido. Tentei reproduzir o problema usando um cartão de crédito inválido e, em seguida, um válido, mas ele não é reproduzido para mim - na preparação, produção ou local.
Meu palpite inicial foi que talvez o método de envio estivesse se perdendo em algum lugar após a primeira exceção válida, mas esse não é o caso, porque vejo que $method
tem o valor correto no momento em que essa exceção é lançada.
O módulo de checkout que estou usando é o AwesomeCheckout - realmente não tenho nenhuma lógica personalizada ao criar pedidos que devem causar problemas aqui, mas podem estar relacionados.
ATUALIZAÇÃO: adicionei um código para tentar recuperar as taxas, caso estejam ausentes.
protected function _validate()
{
if (!$this->getQuote()->isVirtual()) {
$address = $this->getQuote()->getShippingAddress();
$addressValidation = $address->validate();
if ($addressValidation !== true) {
Mage::throwException(
Mage::helper('sales')->__('Please check shipping address information. %s', implode(' ', $addressValidation))
);
}
$method= $address->getShippingMethod();
$rate = $address->getShippingRateByCode($method);
/**
* Start Customization
*/
if (!$this->getQuote()->isVirtual() && !$rate) {
Mage::logException(new Exception("Rate was empty inside quote validate method, trying to forcefully recalculate"));
$this->getQuote()->getShippingAddress()->setCollectShippingRates(true);
$this->getQuote()->setTotalsCollectedFlag(false);
$this->getQuote()->collectTotals();
$rate = $address->getShippingRateByCode($method);
}
/** End Customization **/
if (!$this->getQuote()->isVirtual() && (!$method || !$rate)) {
Mage::throwException(Mage::helper('sales')->__('Please specify a shipping method.'));
}
}