Merge pull request #17450 from mauriciofauth/ajax-error-messages

Add method to AbstractController to send error messages
This commit is contained in:
Maurício Meneghini Fauth 2022-03-20 20:10:11 -03:00 committed by GitHub
commit 4ed3f4cbdd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 105 additions and 10 deletions

View File

@ -895,6 +895,23 @@ $(document).on('ajaxError', function (event, request) {
var details = '';
var state = request.state();
if (
'responseJSON' in request &&
'isErrorResponse' in request.responseJSON &&
request.responseJSON.isErrorResponse
) {
Functions.ajaxShowMessage(
'<div class="alert alert-danger" role="alert">' +
Functions.escapeHtml(request.responseJSON.error) +
'</div>',
false
);
AJAX.active = false;
AJAX.xhr = null;
return;
}
if (request.status !== 0) {
details += '<div>' + Functions.escapeHtml(Functions.sprintf(Messages.strErrorCode, request.status)) + '</div>';
}

View File

@ -146,4 +146,22 @@ abstract class AbstractController
$this->response->setHttpResponseCode(400);
Core::fatalError($errorMessage);
}
/**
* @psalm-param int<400,599> $statusCode
*/
protected function sendErrorResponse(string $message, int $statusCode = 400): void
{
$this->response->setHttpResponseCode($statusCode);
$this->response->setRequestStatus(false);
if ($this->response->isAjax()) {
$this->response->addJSON('isErrorResponse', true);
$this->response->addJSON('message', $message);
return;
}
$this->response->addHTML(Message::error($message)->getDisplay());
}
}

View File

@ -25,15 +25,11 @@ final class DropColumnConfirmationController extends AbstractController
$table = TableName::fromValue($request->getParsedBodyParam('table'));
Assert::allStringNotEmpty($fields);
} catch (InvalidIdentifierName $exception) {
$this->response->setHttpResponseCode(400);
$this->response->setRequestStatus(false);
$this->response->addJSON('message', $exception->getMessage());
$this->sendErrorResponse($exception->getMessage());
return;
} catch (InvalidArgumentException $exception) {
$this->response->setHttpResponseCode(400);
$this->response->setRequestStatus(false);
$this->response->addJSON('message', __('No column selected.'));
$this->sendErrorResponse(__('No column selected.'));
return;
}

View File

@ -6,6 +6,7 @@ namespace PhpMyAdmin\Tests\Controllers;
use PhpMyAdmin\Controllers\AbstractController;
use PhpMyAdmin\Html\MySQLDocumentation;
use PhpMyAdmin\Message;
use PhpMyAdmin\Sanitize;
use PhpMyAdmin\Template;
use PhpMyAdmin\Tests\AbstractTestCase;
@ -58,8 +59,7 @@ class AbstractControllerTest extends AbstractTestCase
$_REQUEST = [];
$response = new ResponseRenderer();
$template = new Template();
$controller = new class ($response, $template) extends AbstractController {
$controller = new class ($response, new Template()) extends AbstractController {
/**
* @psalm-param non-empty-list<non-empty-string> $params
*/
@ -80,4 +80,56 @@ class AbstractControllerTest extends AbstractTestCase
$this->assertSame(200, $response->getHttpResponseCode());
}
public function testSendErrorResponseWithJson(): void
{
$response = new ResponseRenderer();
$response->setAjax(true);
$controller = new class ($response, new Template()) extends AbstractController {
/**
* @psalm-param int<400,599> $statusCode
*/
public function testSendErrorResponse(string $message, int $statusCode = 400): void
{
parent::sendErrorResponse($message, $statusCode);
}
};
$controller->testSendErrorResponse('Error message.', 404);
$this->assertSame(404, $response->getHttpResponseCode());
$this->assertFalse($response->hasSuccessState());
$this->assertSame('', $response->getHTMLResult());
$this->assertSame([
'isErrorResponse' => true,
'message' => 'Error message.',
], $response->getJSONResult());
}
public function testSendErrorResponseWithHtml(): void
{
$response = new ResponseRenderer();
$response->setAjax(false);
$controller = new class ($response, new Template()) extends AbstractController {
/**
* @psalm-param int<400,599> $statusCode
*/
public function testSendErrorResponse(string $message, int $statusCode = 400): void
{
parent::sendErrorResponse($message, $statusCode);
}
};
$controller->testSendErrorResponse('Error message.', 404);
$this->assertSame(404, $response->getHttpResponseCode());
$this->assertFalse($response->hasSuccessState());
$this->assertSame(
Message::error('Error message.')->getDisplay(),
$response->getHTMLResult()
);
$this->assertSame([], $response->getJSONResult());
}
}

View File

@ -28,6 +28,8 @@ class DropColumnConfirmationControllerTest extends AbstractTestCase
$this->dummyDbi->addResult('SHOW TABLES LIKE \'test_table\';', [['test_table']]);
$response = new ResponseRenderer();
$response->setAjax(true);
$template = new Template();
$expected = $template->render('table/structure/drop_confirm', [
'db' => 'test_db',
@ -53,11 +55,16 @@ class DropColumnConfirmationControllerTest extends AbstractTestCase
]);
$response = new ResponseRenderer();
$response->setAjax(true);
(new DropColumnConfirmationController($response, new Template()))($request);
$this->assertSame(400, $response->getHttpResponseCode());
$this->assertFalse($response->hasSuccessState());
$this->assertSame(['message' => 'No column selected.'], $response->getJSONResult());
$this->assertSame([
'isErrorResponse' => true,
'message' => 'No column selected.'
], $response->getJSONResult());
$this->assertSame('', $response->getHTMLResult());
}
@ -71,11 +78,16 @@ class DropColumnConfirmationControllerTest extends AbstractTestCase
]);
$response = new ResponseRenderer();
$response->setAjax(true);
(new DropColumnConfirmationController($response, new Template()))($request);
$this->assertSame(400, $response->getHttpResponseCode());
$this->assertFalse($response->hasSuccessState());
$this->assertSame(['message' => 'The database name must be a non-empty string.'], $response->getJSONResult());
$this->assertSame([
'isErrorResponse' => true,
'message' => 'The database name must be a non-empty string.'
], $response->getJSONResult());
$this->assertSame('', $response->getHTMLResult());
}
}