-
-
Notifications
You must be signed in to change notification settings - Fork 824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add new \Civi\Exception\DBQueryException
& throw that rather than a PEAR_Exception
#25634
Conversation
(Standard links)
|
With regard to naming, here's a list of existing exceptions in
Within
We often look to Drupal conventions. They also use |
So I would probably suggest |
It looks like In the
|
7d2a7c4
to
253489a
Compare
ext/civiimport/Civi/BAO/Import.php
Outdated
} | ||
catch (\PEAR_Exception $e) { | ||
throw new CRM_Core_Exception('Import table no longer exists'); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this part still necessary, if the CRM_Core_Error::exceptionHandler()
now emits CRM_Core_Exception
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@totten - no it is part of one of the PRs to be rebased out once merged first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(merged & up-merged to master)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh, I see. You're aiming for that variant to go into 5.59
- and then this variant goes into master
(but it needs to be reconciled with whatever happened in 5.59
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just rebased out this patch cos I'm trying to deal with another issue in the same file & it will conflict
@@ -1644,6 +1644,8 @@ public static function executeUnbufferedQuery( | |||
* object that holds the results of the query | |||
* NB - if this is defined as just returning a DAO phpstorm keeps pointing | |||
* out all the properties that are not part of the DAO | |||
* | |||
* @throws \Civi\Core\Exception\DBQueryException | |||
*/ | |||
public static function &executeQuery( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just trying to think this through... I do like having that clearly documented for someone who's reading the docblock.
But... DBQueryException
is a "checked" exception (insofar as it's not a \RuntimeException
), and PHPStorm will nag you to catch it. The thing about that... when searching universe
, there were only 2-3 small places which actually tried to catch an exception like this. But there are.. about 5,000 places in universe/ext/
that call executeQuery()
. So won't the tooling expect you to put catch()
or @throws
on all of ~5,000 of them (plus, for @throws
, the same on every downstream call)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function actually throws 2 different types of exceptions - it also throws an exception if the validation is invalid.
We kind of have the problem in practice anyway - as all the places that call the api or singleValueQuery
are required to catch CRM_Core_Exception
or document it (and if you catch or document CRM_Core_Exception
that covers this.
I took a look & drupal DOES declare an exception on it's prepare
so I guess drupal code has to catch those things.
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21Query%21Sql%21Query.php/10
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so I guess drupal code has to catch those things...
I started looking at their arrangement, and... it's a bit of a rabbit-hole. For example, here's a basic query:
\Drupal::database()->query("SELECT id, example FROM {mytable}")->fetchAll();
The type-hints have a lot of abstraction there. Both in the immediate call chain (e.g. abstract class Connection
, interface StatementInterface
) and in the various @throws
. On Connection::query()
, it @throws
one of these:
class DatabaseExceptionWrapper extends \RuntimeException implements DatabaseException {
So from the callers' POV, that's an unchecked exception. But if you want to catch it, then you should probably go for DatabaseException
instead of DatabaseExceptionWrapper
.
But there's more! In the class you linked, the protected prepare()
declares a @throws QueryException
but the public execute()
doesn't declare any @throws
at all. So they just hide that one...
I dunno, after looking at Drupal's example, I feel more confused. 🙄
.all the places that call the api or singleValueQuery are required to catch CRM_Core_Exception or document it (and if you catch or document CRM_Core_Exception that covers this.
Very good point!
33b096c
to
bfdd5ac
Compare
Hmm - what is happening with the tests - test this please (this is one of 2 prs I keep trying to get tests to run on today) |
This one seems to be an issue with the updated This one seems to be an out-of-memory.
I checked the build-log on this node, and there were two cases of this -- both were on this PR (25634) when testing the |
@eileenmcnaughton I get the same out-of-memory problem when I run |
public static function exceptionHandler($pearError) {
CRM_Core_Error::debug_var('Fatal Error Details', self::getErrorDetails($pearError), TRUE, TRUE, '', PEAR_LOG_ERR);
CRM_Core_Error::backtrace('backTrace', TRUE);
if ($pearError instanceof DB_Error) {
throw new DBQueryException($pearError->getMessage(), $pearError->getCode(), ['exception' => $pearError]);
}
throw new CRM_Core_Exception($pearError->getMessage(), $pearError->getCode(), ['exception' => $pearError]);
} So I checked out the patch and did some runs of
(ED: I haven't dug any further to figure what or why of the memory usage.) |
That sucks - the exception is in the I think we need to get the preliminary PRs merged & then once that is sorted I will dig into where memory is not released |
bfdd5ac
to
376dc75
Compare
Well I don't quite have the fix yet but the issue is apiv3 handling of errors & specifically backtrace.. This line civicrm-core/Civi/Test/Api3TestTrait.php Line 86 in 92400d7
is having a cow - presumably the way the trace is attached to the because it is now funnelling into the first civicrm-core/Civi/API/Kernel.php Lines 89 to 97 in ca5063d
|
Argh CRM_Core_ErrorTest::testDBError with data set "invalid_syntax" (array('FROM civicrm_contact', 'DB Error: syntax error', -2, 'Invalid Query syntax error Yo...line 1', 1064)) |
c2b9a52
to
52013b5
Compare
@totten it passed! |
…EAR_ERROR Fix api v3 handling of exception to not include the exception (fails on print_r()) m
…rocess Show user sanitised message
@totten I think this is mergeable now (I thought we had merged it & got tripped up when I couldn't catch the new exception type :-)) |
52013b5
to
1527308
Compare
We just branched RC yesterday. I think that makes it a good time to merge this. |
Overview
Add new
\Civi\Core\Exception\DBQueryException
& throw that rather than aPEAR_Exception
Before
When a DB error occurs an instance of
PEAR_Exception
is thrown.CRM_Core_Exception
extendsPEAR_Exception
and is the target of mosttry-catch
blocks but does NOT catch thePEAR_Exception
After
\Civi\Core\Exception\DBQueryException
is thrown for DB exceptions, otherwiseCRM_Core_Exceptions
are thrownTechnical Details
Comments