He estado recibiendo registros de excepciones para este error en producción, pero no puedo reproducir el problema en mi entorno local o provisional, por lo que ha sido bastante difícil de solucionar.
El error se origina Mage_Sales_Model_Service_Quote::_validate()
porque el $rate
devuelto por $rate = $address->getShippingRateByCode($method)
está vacío.
He agregado algunos registros para intentar tener una mejor idea de lo que estaba sucediendo, y puedo ver que $method
contiene el método de envío correcto.
Mi mejor conjetura es que en algún momento del proceso, las tarifas de envío se eliminan antes de cuando deberían serlo.
Me di cuenta de que cada vez que se produce esta excepción, ocurre inmediatamente después de una excepción legítima, como una tarjeta de crédito no válida. Intenté reproducir el problema usando una tarjeta de crédito no válida, luego una válida, pero no se reproduce para mí, ya sea en escena, producción o local.
Mi presentimiento inicial fue que tal vez el método de envío se estaba perdiendo en algún lugar después de la primera excepción válida, pero ese no es el caso, porque veo que $method
tiene el valor correcto en el momento en que se lanza esta excepción.
El módulo de pago que estoy usando es AwesomeCheckout, que yo sepa no tiene ninguna lógica personalizada al crear pedidos que deberían causar problemas aquí, pero podrían estar relacionados.
ACTUALIZACIÓN: agregué un código para intentar recordar las tasas si faltan.
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.'));
}
}