]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/api/ApiUsageException.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / api / ApiUsageException.php
1 <?php
2 /**
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16  * http://www.gnu.org/copyleft/gpl.html
17  *
18  * @file
19  * @defgroup API API
20  */
21
22 /**
23  * This exception will be thrown when dieUsage is called to stop module execution.
24  *
25  * @ingroup API
26  * @deprecated since 1.29, use ApiUsageException instead
27  */
28 class UsageException extends MWException {
29
30         private $mCodestr;
31
32         /**
33          * @var null|array
34          */
35         private $mExtraData;
36
37         /**
38          * @param string $message
39          * @param string $codestr
40          * @param int $code
41          * @param array|null $extradata
42          */
43         public function __construct( $message, $codestr, $code = 0, $extradata = null ) {
44                 parent::__construct( $message, $code );
45                 $this->mCodestr = $codestr;
46                 $this->mExtraData = $extradata;
47
48                 if ( !$this instanceof ApiUsageException ) {
49                         wfDeprecated( __METHOD__, '1.29' );
50                 }
51
52                 // This should never happen, so throw an exception about it that will
53                 // hopefully get logged with a backtrace (T138585)
54                 if ( !is_string( $codestr ) || $codestr === '' ) {
55                         throw new InvalidArgumentException( 'Invalid $codestr, was ' .
56                                 ( $codestr === '' ? 'empty string' : gettype( $codestr ) )
57                         );
58                 }
59         }
60
61         /**
62          * @return string
63          */
64         public function getCodeString() {
65                 wfDeprecated( __METHOD__, '1.29' );
66                 return $this->mCodestr;
67         }
68
69         /**
70          * @return array
71          */
72         public function getMessageArray() {
73                 wfDeprecated( __METHOD__, '1.29' );
74                 $result = [
75                         'code' => $this->mCodestr,
76                         'info' => $this->getMessage()
77                 ];
78                 if ( is_array( $this->mExtraData ) ) {
79                         $result = array_merge( $result, $this->mExtraData );
80                 }
81
82                 return $result;
83         }
84
85         /**
86          * @return string
87          */
88         public function __toString() {
89                 return "{$this->getCodeString()}: {$this->getMessage()}";
90         }
91 }
92
93 /**
94  * Exception used to abort API execution with an error
95  *
96  * If possible, use ApiBase::dieWithError() instead of throwing this directly.
97  *
98  * @ingroup API
99  * @note This currently extends UsageException for backwards compatibility, so
100  *  all the existing code that catches UsageException won't break when stuff
101  *  starts throwing ApiUsageException. Eventually UsageException will go away
102  *  and this will (probably) extend MWException directly.
103  */
104 class ApiUsageException extends UsageException implements ILocalizedException {
105
106         protected $modulePath;
107         protected $status;
108
109         /**
110          * @param ApiBase|null $module API module responsible for the error, if known
111          * @param StatusValue $status Status holding errors
112          * @param int $httpCode HTTP error code to use
113          */
114         public function __construct(
115                 ApiBase $module = null, StatusValue $status, $httpCode = 0
116         ) {
117                 if ( $status->isOK() ) {
118                         throw new InvalidArgumentException( __METHOD__ . ' requires a fatal Status' );
119                 }
120
121                 $this->modulePath = $module ? $module->getModulePath() : null;
122                 $this->status = $status;
123
124                 // Bug T46111: Messages in the log files should be in English and not
125                 // customized by the local wiki.
126                 $enMsg = clone $this->getApiMessage();
127                 $enMsg->inLanguage( 'en' )->useDatabase( false );
128                 parent::__construct(
129                         ApiErrorFormatter::stripMarkup( $enMsg->text() ),
130                         $enMsg->getApiCode(),
131                         $httpCode,
132                         $enMsg->getApiData()
133                 );
134         }
135
136         /**
137          * @param ApiBase|null $module API module responsible for the error, if known
138          * @param string|array|Message $msg See ApiMessage::create()
139          * @param string|null $code See ApiMessage::create()
140          * @param array|null $data See ApiMessage::create()
141          * @param int $httpCode HTTP error code to use
142          * @return static
143          */
144         public static function newWithMessage(
145                 ApiBase $module = null, $msg, $code = null, $data = null, $httpCode = 0
146         ) {
147                 return new static(
148                         $module,
149                         StatusValue::newFatal( ApiMessage::create( $msg, $code, $data ) ),
150                         $httpCode
151                 );
152         }
153
154         /**
155          * @return ApiMessage
156          */
157         private function getApiMessage() {
158                 $errors = $this->status->getErrorsByType( 'error' );
159                 if ( !$errors ) {
160                         $errors = $this->status->getErrors();
161                 }
162                 if ( !$errors ) {
163                         $msg = new ApiMessage( 'apierror-unknownerror-nocode', 'unknownerror' );
164                 } else {
165                         $msg = ApiMessage::create( $errors[0] );
166                 }
167                 return $msg;
168         }
169
170         /**
171          * Fetch the responsible module name
172          * @return string|null
173          */
174         public function getModulePath() {
175                 return $this->modulePath;
176         }
177
178         /**
179          * Fetch the error status
180          * @return StatusValue
181          */
182         public function getStatusValue() {
183                 return $this->status;
184         }
185
186         /**
187          * @deprecated Do not use. This only exists here because UsageException is in
188          *  the inheritance chain for backwards compatibility.
189          * @inheritDoc
190          */
191         public function getCodeString() {
192                 wfDeprecated( __METHOD__, '1.29' );
193                 return $this->getApiMessage()->getApiCode();
194         }
195
196         /**
197          * @deprecated Do not use. This only exists here because UsageException is in
198          *  the inheritance chain for backwards compatibility.
199          * @inheritDoc
200          */
201         public function getMessageArray() {
202                 wfDeprecated( __METHOD__, '1.29' );
203                 $enMsg = clone $this->getApiMessage();
204                 $enMsg->inLanguage( 'en' )->useDatabase( false );
205
206                 return [
207                         'code' => $enMsg->getApiCode(),
208                         'info' => ApiErrorFormatter::stripMarkup( $enMsg->text() ),
209                 ] + $enMsg->getApiData();
210         }
211
212         /**
213          * @inheritDoc
214          */
215         public function getMessageObject() {
216                 return $this->status->getMessage();
217         }
218
219         /**
220          * @return string
221          */
222         public function __toString() {
223                 $enMsg = clone $this->getApiMessage();
224                 $enMsg->inLanguage( 'en' )->useDatabase( false );
225                 $text = ApiErrorFormatter::stripMarkup( $enMsg->text() );
226
227                 return get_class( $this ) . ": {$enMsg->getApiCode()}: {$text} "
228                         . "in {$this->getFile()}:{$this->getLine()}\n"
229                         . "Stack trace:\n{$this->getTraceAsString()}";
230         }
231
232 }