如何从Sabre API获取错误消息?getReservationRQ报错信息无法输出求助
Hey there, let's break down why you're not capturing those error messages properly from the getReservationRQ API response. Looking at your code snippet, there are a few common pitfalls that might be tripping you up—let's walk through them step by step:
1. First: Reveal the Full XML Response
You’ve got a commented-out line that prints the raw XML—uncomment that first! This is the most critical debugging step. Error responses often have different structures than successful ones (e.g., a SOAP Fault instead of a GetReservationRS block), and you need to see exactly what the API is sending back.
// Uncomment this to see the full raw response (debug only) echo "<textarea>" . htmlspecialchars($xml->asXML()) . "</textarea>";
Pro tip: Use htmlspecialchars() to avoid XML tags breaking your page layout.
2. Check for SOAP-Level Faults First
Many APIs return SOAP Faults for low-level errors (like bad auth, invalid request formatting, or server issues) instead of wrapping errors in the business-level GetReservationRS structure. Your current code skips checking for these entirely.
Add a check for SOAP Faults before looking for business errors:
$ns = $xml->getNamespaces(true); $soap_env_ns = $ns['soap-env'] ?? ''; // Handle SOAP-level faults (common for auth/request errors) if (!empty($soap_env_ns) && isset($xml->children($soap_env_ns)->Body->Fault)) { $fault = $xml->children($soap_env_ns)->Body->Fault; $error_code = (string)$fault->faultcode; $error_msg = (string)$fault->faultstring; // Log or display the SOAP error error_log("SOAP Error: {$error_code} - {$error_msg}"); return; // Exit early since this is a fatal request error }
3. Verify Namespace & Node Hierarchy
Your code uses the stl17 namespace for GetReservationRS, but:
- The
stl17prefix might not match the actual namespace prefix in the error response (sometimes APIs usestlor a different prefix for errors) - You might be accessing the node hierarchy incorrectly (e.g.,
Errorsmight contain individualErrornodes instead of being iterable directly)
After checking the raw XML, adjust your namespace and node path. For example, if the raw error shows stl17:Errors under stl17:GetReservationRS, fix your loop to target individual Error nodes:
$stl17_ns = $ns['stl17'] ?? ''; if (!empty($stl17_ns)) { // Navigate to the business response node correctly $reservation_rs = $xml->children($soap_env_ns)->Body->children($stl17_ns)->GetReservationRS; // Check if Errors exist, then loop through individual Error nodes if (isset($reservation_rs->Errors)) { foreach ($reservation_rs->Errors->Error as $error) { $error_code = (string)$error->ErrorCode; $error_desc = (string)$error->ErrorDescription; // Log or display the business error error_log("Business Error: {$error_code} - {$error_desc}"); } } }
4. Handle Edge Cases
- If the API returns an empty
GetReservationRSon error, your current code would throw a notice when trying to accessGetReservationRS->Errors—add a check for the existence ofGetReservationRSfirst. - Some APIs use different namespaces for errors vs. successful responses—double-check the
xmlnsattributes in the raw XML for the error nodes.
Full Revised Function Example
private function handle_api_error($xml) { // Debug: Print full XML response (comment out in production) echo "<textarea>" . htmlspecialchars($xml->asXML()) . "</textarea>"; $ns = $xml->getNamespaces(true); $soap_env_ns = $ns['soap-env'] ?? ''; $stl17_ns = $ns['stl17'] ?? ''; // 1. Handle SOAP-level faults if (!empty($soap_env_ns) && isset($xml->children($soap_env_ns)->Body->Fault)) { $fault = $xml->children($soap_env_ns)->Body->Fault; $error_details = "SOAP Fault: " . (string)$fault->faultcode . " - " . (string)$fault->faultstring; error_log($error_details); return $error_details; } // 2. Handle business-level errors if (!empty($stl17_ns)) { $body = $xml->children($soap_env_ns)->Body; $reservation_rs = $body->children($stl17_ns)->GetReservationRS ?? null; if ($reservation_rs && isset($reservation_rs->Errors)) { $error_list = []; foreach ($reservation_rs->Errors->Error as $error) { $error_code = (string)$error->ErrorCode; $error_desc = (string)$error->ErrorDescription; $error_list[] = "Error {$error_code}: {$error_desc}"; } $error_details = implode("\n", $error_list); error_log($error_details); return $error_details; } } // 3. Catch-all for unexpected error structures $error_details = "Unexpected error response structure"; error_log($error_details); return $error_details; }
内容的提问来源于stack exchange,提问作者A Kaufman

