Skip to content
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

Truncate Doctrine\DBAL\Exception\DriverException message if too long #2523

Closed
shtrom opened this issue Sep 28, 2016 · 9 comments
Closed

Truncate Doctrine\DBAL\Exception\DriverException message if too long #2523

shtrom opened this issue Sep 28, 2016 · 9 comments

Comments

@shtrom
Copy link

shtrom commented Sep 28, 2016

Hi have an issue---triggered by ownCloud and an erroneous vCard with a duplicated PHOTO field---where a database insertion request into MySQL via the Doctrine DBAL fails.

Essentially, the blob inserted is too big for MySQL, and it issues a Syntax error or access violation: 1118 The size of BLOB/TEXT data inserted in one transaction is greater than 10% of redo log size.” which gets transformed into a Doctrine\DBAL\Exception\DriverException.

The message for the exception is An exception occurred while executing [QUERY] with params [PARAMS]. This is where the issue with Doctrine is: the blob is about 9MiB at this stage, and it is dumped verbatim as part of the PARAMS bit in the error message. This makes the Exception a bit hard to understand, as it is not concise enough, and this makes log files grow at a very very high rate.

A solution to this problem would be to either

  • truncate or ellipsise PARAMS longer than a given threshold in the error message, e.g., BEGIN:VCARD\r ... END:VCARD\r(line ending might or might not be a good idea to rely on)
  • not reproduce blobs, and replace them altogether with something like BLOB of 9MiB, or
  • a combination of both: BEGIN:VCARD\r [about 9MiB of blob] END:VCARD\r.

Note that my example is with ownCloud and vCards, but the problem is more generic, with any blob too big for comfortable display.

shtrom added a commit to shtrom/dbal that referenced this issue Sep 28, 2016
Signed-off-by: Olivier Mehani <shtrom@ssji.net>
@kimhemsoe
Copy link
Member

Sounds to me that it is the exception handler which prints out the exception. Any reason why this could not be fixed in the presentation of the exception?

@shtrom
Copy link
Author

shtrom commented Sep 28, 2016

This could work. However the DBALException (well, driverExceptionDuringQuery) has a better view into which $param is the longest, and can cut the cruft more accurately, without touching the others.

In my example above, there is still valuable information at the end of the exception (in the output of ->getMessage()), which would otherwise be removed at the logging site by, e.g., an mb_strimwidth, as I've used in my test above.

@shtrom
Copy link
Author

shtrom commented Sep 28, 2016

Yup, the fix in the commit above fixes the issue nicely, while retaining useful information. It truncates the long blob properly, but retains useful things such as the stacktrace after that.

@Ocramius
Copy link
Member

Looking at #2524, I think this is up to the exception handler printing the error. It is indeed a lot of data, but imagine having an incorrect character at position 2500 (invalid encoding), and then going mad :-P

@shtrom
Copy link
Author

shtrom commented Sep 29, 2016

It is indeed a lot of data, but imagine having an incorrect character at position 2500 (invalid encoding)

Right, I didn't consider this.

That said, if the exception handler truncates the whole message, you will lose the information too, but also the rest of the error message, with a potentially much more helpful “invalid encoding”. If we just truncate the parameter here, the exception handler will still be able to get and display the error message from the database.

Perhaps there can be a middle ground, where we give a formatted message, but add the full parameters to the Exception as additional properties, or the other way round?

@shtrom
Copy link
Author

shtrom commented Sep 29, 2016

If we just truncate the parameter here, the exception handler will still be able to get and display the error message from the database.

What I mean is something like in this pseudo example.

Truncate in the exception handler:

An exception occurred while executing [QUERY] with params [PARAM1, PARAM2, PARA...

Truncate the parameter in in the exception formatter:

An exception occurred while executing [QUERY] with params [PARAM1, PARAM2, PARA..., PARAM4]: Syntax error or access violation: 1118 The size of BLOB/TEXT data inserted in one transaction is greater than 10% of redo log size.

I think truncating late leads to a much less useful error message.

@scaytrase
Copy link

Is it possible just to make the original message (or the whole driver exception) from dbal driver exception https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Exception/DriverException.php#L38 accessible via doctrine exception interface?

In out case we handle some exception conversions by ourselves so it would be handy just to have a string like

SQLSTATE[22003]: Numeric value out of range: 7 ERROR:  value \"9223372036854775807\" is out of range for type integer",

to view

@morozov
Copy link
Member

morozov commented Dec 12, 2021

This should have been fixed by #4387.

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 22, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants