1<?php 2/** 3 * Copyright 2017 Facebook, Inc. 4 * 5 * You are hereby granted a non-exclusive, worldwide, royalty-free license to 6 * use, copy, modify, and distribute this software in source code or binary 7 * form for use in connection with the web services and APIs provided by 8 * Facebook. 9 * 10 * As with any software that integrates with the Facebook platform, your use 11 * of this software is subject to the Facebook Developer Principles and 12 * Policies [http://developers.facebook.com/policy/]. This copyright notice 13 * shall be included in all copies or substantial portions of the software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 * 23 */ 24namespace Facebook\Exceptions; 25 26use Facebook\FacebookResponse; 27 28/** 29 * Class FacebookResponseException 30 * 31 * @package Facebook 32 */ 33class FacebookResponseException extends FacebookSDKException 34{ 35 /** 36 * @var FacebookResponse The response that threw the exception. 37 */ 38 protected $response; 39 40 /** 41 * @var array Decoded response. 42 */ 43 protected $responseData; 44 45 /** 46 * Creates a FacebookResponseException. 47 * 48 * @param FacebookResponse $response The response that threw the exception. 49 * @param FacebookSDKException $previousException The more detailed exception. 50 */ 51 public function __construct(FacebookResponse $response, FacebookSDKException $previousException = null) 52 { 53 $this->response = $response; 54 $this->responseData = $response->getDecodedBody(); 55 56 $errorMessage = $this->get('message', 'Unknown error from Graph.'); 57 $errorCode = $this->get('code', -1); 58 59 parent::__construct($errorMessage, $errorCode, $previousException); 60 } 61 62 /** 63 * A factory for creating the appropriate exception based on the response from Graph. 64 * 65 * @param FacebookResponse $response The response that threw the exception. 66 * 67 * @return FacebookResponseException 68 */ 69 public static function create(FacebookResponse $response) 70 { 71 $data = $response->getDecodedBody(); 72 73 if (!isset($data['error']['code']) && isset($data['code'])) { 74 $data = ['error' => $data]; 75 } 76 77 $code = isset($data['error']['code']) ? $data['error']['code'] : null; 78 $message = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error from Graph.'; 79 80 if (isset($data['error']['error_subcode'])) { 81 switch ($data['error']['error_subcode']) { 82 // Other authentication issues 83 case 458: 84 case 459: 85 case 460: 86 case 463: 87 case 464: 88 case 467: 89 return new static($response, new FacebookAuthenticationException($message, $code)); 90 // Video upload resumable error 91 case 1363030: 92 case 1363019: 93 case 1363037: 94 case 1363033: 95 case 1363021: 96 case 1363041: 97 return new static($response, new FacebookResumableUploadException($message, $code)); 98 } 99 } 100 101 switch ($code) { 102 // Login status or token expired, revoked, or invalid 103 case 100: 104 case 102: 105 case 190: 106 return new static($response, new FacebookAuthenticationException($message, $code)); 107 108 // Server issue, possible downtime 109 case 1: 110 case 2: 111 return new static($response, new FacebookServerException($message, $code)); 112 113 // API Throttling 114 case 4: 115 case 17: 116 case 32: 117 case 341: 118 case 613: 119 return new static($response, new FacebookThrottleException($message, $code)); 120 121 // Duplicate Post 122 case 506: 123 return new static($response, new FacebookClientException($message, $code)); 124 } 125 126 // Missing Permissions 127 if ($code == 10 || ($code >= 200 && $code <= 299)) { 128 return new static($response, new FacebookAuthorizationException($message, $code)); 129 } 130 131 // OAuth authentication error 132 if (isset($data['error']['type']) && $data['error']['type'] === 'OAuthException') { 133 return new static($response, new FacebookAuthenticationException($message, $code)); 134 } 135 136 // All others 137 return new static($response, new FacebookOtherException($message, $code)); 138 } 139 140 /** 141 * Checks isset and returns that or a default value. 142 * 143 * @param string $key 144 * @param mixed $default 145 * 146 * @return mixed 147 */ 148 private function get($key, $default = null) 149 { 150 if (isset($this->responseData['error'][$key])) { 151 return $this->responseData['error'][$key]; 152 } 153 154 return $default; 155 } 156 157 /** 158 * Returns the HTTP status code 159 * 160 * @return int 161 */ 162 public function getHttpStatusCode() 163 { 164 return $this->response->getHttpStatusCode(); 165 } 166 167 /** 168 * Returns the sub-error code 169 * 170 * @return int 171 */ 172 public function getSubErrorCode() 173 { 174 return $this->get('error_subcode', -1); 175 } 176 177 /** 178 * Returns the error type 179 * 180 * @return string 181 */ 182 public function getErrorType() 183 { 184 return $this->get('type', ''); 185 } 186 187 /** 188 * Returns the raw response used to create the exception. 189 * 190 * @return string 191 */ 192 public function getRawResponse() 193 { 194 return $this->response->getBody(); 195 } 196 197 /** 198 * Returns the decoded response used to create the exception. 199 * 200 * @return array 201 */ 202 public function getResponseData() 203 { 204 return $this->responseData; 205 } 206 207 /** 208 * Returns the response entity used to create the exception. 209 * 210 * @return FacebookResponse 211 */ 212 public function getResponse() 213 { 214 return $this->response; 215 } 216} 217