Skip to content

Commit ad9bb39

Browse files
committed
AC-746: Malformed request body or parameters cause "Internal Server Error"
Determine if an exception is a client error based on the exception type Plugin for search criteria filter groups
1 parent 05cdc48 commit ad9bb39

File tree

3 files changed

+94
-17
lines changed

3 files changed

+94
-17
lines changed
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All rights reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Webapi\Model\Plugin\Framework\Api;
9+
10+
use Magento\Framework\Api\Filter;
11+
use Magento\Framework\Exception\InputException;
12+
use Magento\Framework\Phrase;
13+
14+
/**
15+
* This plugin validates the search criteria field, value and condition type.
16+
*/
17+
class FilterPlugin
18+
{
19+
/**
20+
* Validate the search criteria field.
21+
*
22+
* @param Filter $filter
23+
* @param string $result
24+
* @return string
25+
*/
26+
public function afterGetField(Filter $filter, $result)
27+
{
28+
if (empty($result) && !empty($filter->getValue())) {
29+
throw new InputException(
30+
new Phrase(
31+
'Invalid search filter: %1 cannot be empty.',
32+
["field"]
33+
)
34+
);
35+
}
36+
return $result;
37+
}
38+
39+
/**
40+
* Validate the search criteria value.
41+
*
42+
* @param Filter $filter
43+
* @param string $result
44+
* @return string
45+
*/
46+
public function afterGetValue(Filter $filter, $result)
47+
{
48+
if (empty($result) && !empty($filter->getField())) {
49+
throw new InputException(
50+
new Phrase(
51+
'Invalid search filter: %1 cannot be empty.',
52+
["value"]
53+
)
54+
);
55+
}
56+
return $result;
57+
}
58+
59+
/**
60+
* Validate the search criteria condition type.
61+
*
62+
* @param Filter $filter
63+
* @param string $result
64+
* @return string
65+
*/
66+
public function afterGetConditionType(Filter $filter, $result)
67+
{
68+
if (empty($filter->getField()) || empty($filter->getValue())) {
69+
throw new InputException(
70+
new Phrase(
71+
'Invalid search filter: %1 and %2 cannot be empty.',
72+
["field", "value"]
73+
)
74+
);
75+
}
76+
return $result;
77+
}
78+
}

app/code/Magento/Webapi/etc/webapi_rest/di.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,7 @@
8383
<type name="Magento\Store\Model\Validation\StoreCodeValidator">
8484
<plugin name="check_if_parsed_store_code_is_valid" type="Magento\Webapi\Model\Plugin\Store\Model\Validation\StoreCodeValidator"/>
8585
</type>
86+
<type name="Magento\Framework\Api\Filter">
87+
<plugin name="validate_search_criteria_field" type="Magento\Webapi\Model\Plugin\Framework\Api\FilterPlugin" sortOrder="10"/>
88+
</type>
8689
</config>

lib/internal/Magento/Framework/Webapi/ErrorProcessor.php

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,6 @@ class ErrorProcessor
4343

4444
public const DATA_FORMAT_XML = 'xml';
4545

46-
/**
47-
* Client error keywords
48-
*/
49-
private const CLIENT_ERROR_KEYWORDS = [
50-
'sqlstate',
51-
'missing required',
52-
'doesn\'t exist',
53-
'not found',
54-
'not authorized',
55-
];
56-
5746
/**
5847
* @var \Magento\Framework\Json\Encoder $encoder
5948
*/
@@ -183,18 +172,25 @@ public function maskException(\Exception $exception)
183172
}
184173

185174
/**
186-
* Determine if an exception is a client error based on message content and context
175+
* Determine if an exception is a client error based on the exception type
187176
*
188177
* @param \Exception $exception
189178
* @return bool
190179
*/
191180
private function isClientError(\Exception $exception)
192181
{
193-
$message = strtolower($exception->getMessage());
194-
195-
return array_filter(self::CLIENT_ERROR_KEYWORDS, function($keyword) use ($message) {
196-
return strpos($message, $keyword) !== false;
197-
}) !== [];
182+
if ($exception instanceof \Zend_Db_Exception
183+
|| $exception instanceof \Zend_Db_Adapter_Exception
184+
|| $exception instanceof \Zend_Db_Statement_Exception
185+
|| $exception instanceof \PDOException
186+
|| $exception instanceof \InvalidArgumentException
187+
|| $exception instanceof \BadMethodCallException
188+
|| $exception instanceof \UnexpectedValueException
189+
|| $exception instanceof \Magento\Framework\Search\Request\NonExistingRequestNameException
190+
) {
191+
return true;
192+
}
193+
return false;
198194
}
199195

200196
/**

0 commit comments

Comments
 (0)