Ошибки в waNet Принято
1. При получении сжатых данных ('Content-Encoding: gzip') результат не распаковывается перед декодированием в json/xml и возникает ошибка.
2. Результат предыдущего запроса обнуляется не вначале следующего запроса, а под конец, поэтому в случае ошибки в необработанном ответе может оказывается результат предыдущего запроса.
3. Результат запроса декодируется до проверки кода по 'expected_http_code', соответственно вместо исключения о неверном результате запроса получаем исключение о неверном формате данных (выполняется бесполезное декодирование).
4. Не логируются ошибки при декодировании json.
Вот как примерно должно быть:
public function query($url, $content = array(), $method = self::METHOD_GET, $callback = null) { // Reset response $this->decoded_response = null; $this->raw_response = null; $this->response_header = array('http_code' => 500); $this->buildRequest($url, $content, $method); $this->startQuery(); switch ($this->getTransport($url)) { case self::TRANSPORT_CURL: $this->raw_response = $this->runCurl($url, $content, $method, array(), $callback); break; case self::TRANSPORT_FOPEN: $this->raw_response = $this->runStreamContext($url, $content, $method); break; case self::TRANSPORT_SOCKET: $this->raw_response = $this->runSocketContext($url, $content, $method); break; default: throw new waException('There no suitable network transports', 500); } if ($this->raw_response instanceof self) { return $this->raw_response; } $this->onQueryComplete($this->raw_response); return $this->getResponse(); } protected function onQueryComplete($response) { // @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding $encoding = $this->getResponseHeader('Content-Encoding'); if (in_array($encoding, array('gzip', 'x-gzip')) && function_exists('gzinflate')) { // @see http://php.net/manual/ru/function.gzinflate.php#100775 $response = gzinflate(substr($response, 10, -8)); } if ($this->options['expected_http_code'] !== null) { if (!is_array($this->options['expected_http_code'])) { $this->options['expected_http_code'] = preg_split('@[,:;.\s]+@', $this->options['expected_http_code']); } $code = $this->getResponseHeader('http_code'); if (!in_array($code, $this->options['expected_http_code'])) { throw new waException($response, $code ? $code : 500); } } $this->decodeResponse($response); } protected function decodeResponse($response) { switch ($this->options['format']) { case self::FORMAT_JSON: try { $this->decoded_response = waUtils::jsonDecode($response, true); } catch (waException $e) { $this->log($e->getMessage()); throw new waException('Error while decode JSON response: '.$e->getMessage(), $e->getCode()); } break; case self::FORMAT_XML: libxml_clear_errors(); libxml_use_internal_errors(true); libxml_disable_entity_loader(false); $xml_options = LIBXML_NOCDATA | LIBXML_NOENT | LIBXML_NONET; $this->decoded_response = @simplexml_load_string($response, null, $xml_options); if ($this->decoded_response === false) { /** * @var LibXMLError $error */ if ($error = libxml_get_last_error()) { $this->log($error->message); throw new waException('Error while decode XML response: '.$error->message, $error->code); } } break; default: $this->decoded_response = $response; } }
10 комментариев
3 пункт спорный
многие api возвращают ошибку, например авторизации, с сооветствующим кодом и объект ошибки в теле ответа.
Ну, можно, конечно, поймав исключение, декодировать самостоятельно. Но зачем?
В большинстве случаев ошибки 4хх имеют формат строки или вообще не имеет тела и при попытке их декодировать возникает ошибка. Предложенный вариант таких проблем не имеет, если требуется декодировать ответ для 5хх ошибок которые действительно идут чаще всего в том же формате, то их нужно указать в 'expected_http_code'.
а воз поныне там..
5. При вызове multiQuery его $options сохраняются в waNet::$master_options и перекрывают все настройки других запросов в том числе и настройки из конфига net.php. Пример: при вызове расчёта доставки из shopHelper вызывается расчёт всех способов через multiQuery, при этом в опциях вызова жёстко задан таймаут 10с. Таким образом ни настройка "нового" чекаута, ни опции из конфига net.php, ни тем более опция таймаута, устанавливаемая в плагине расчёта доставки никакого влияния не оказывают. Таймаут для всех запросов жёстко фиксируется в 10 сек.
если ты об этом
то данное значение берется из настроек магазина, 10с просто значение по умолчанию.
Хотя я нихрена не понимаю какое это имеет отношение к теме :)
У меня в настройках магазина (чекаута) стоит 60 с. Но передаётся все равно 10
поздравляю ты нашел очередной баг WA, хотя учитывая что эта настройка только в оформлении заказа в корзине, то спишут на фичу )
меня смущает
я не разбираюсь в этих мультизапросах, но разве это означает ожидание и по новой?
Настройка от "нового чекаута", похоже, работает только именно в "новом чекауте". Тогда как этот расчёт из shopHelper вызывается ещё много где, например при оформлении через админку. И там только дефолтные 10 сек попадают
не 100% - баг т.к. $master_options будет замещать передаваемые значения, причем свойство еще и приватное т.ч. никакого баловства с наследованием
Я отнаследовал waNet и перегрузил конструктор