Problem/Motivation
When a services.yml file is badly-formed, doing a container rebuild just gives you an error with a snippet of the problem:
> A colon cannot be used in an unquoted mapping value at line 4 (near " - { name: route_enhancer }").
It doesn't tell you which file went wrong.
Steps to reproduce
Proposed resolution
DrupalKernel::compileContainer() should wrap calls to YamlFileLoader->load() with a try/catch block, and rethrow the exception with additional information about the filename.
This should be done in DrupalKernel rather than YamlFileLoader, as YamlFileLoader should be kept as close as possible to the Symfony version of that class that is is a fork of.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #44 | 3283035-44.patch | 2.03 KB | spokje |
| #44 | interdiff.39-44.txt | 642 bytes | spokje |
Issue fork drupal-3283035
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
bruno.bicudoJust thinking here, but would something like this work? (just illustrating here)
I don't know if it's a good approach (and what would be a good one XD). Any help is appreciated.
Comment #3
joachim commented> catch (\Exception $e) {
It might be a more specific exception we should catch -- what does YamlLoader throw?
> \Drupal::logger('php')->error('The file ' . $filename . 'failed to load due to error: ' . $e->getMessage());
We should throw a new exception, not log and carry on. If a services.yml is not parseable, then Drupal can't run.
Comment #4
longwaveSymfony now has some code to handle this: https://github.com/symfony/dependency-injection/blob/f0d7ec8b5d84e262498...
We use a custom Yaml parser (which invokes PECL or Symfony as available) so we can't copy the code exactly. But I suggest we do copy the error message from Symfony so our YamlFileLoader is closer to theirs.
Comment #5
bruno.bicudo@joachin You're right. We should halt the execution. Looks like it's throwing an InvalidDataTypeException atm. Should i keep it?
@longwave i like the message from symfony.
Comment #6
longwaveI would catch the InvalidDataTypeException and throw InvalidArgumentException, as that is used for all other exceptions in YamlFileLoader - the filename argument is considered invalid because of a parse error, in this case.
Comment #7
bruno.bicudoOk so, we're catching
InvalidDataTypeExceptionhere and throwingInvalidArgumentExceptionin bothloadcalls.I attached 2 screenshots showing the current error message and the "new" one.
Hope it helps. Kindly review it :)
Comment #8
bruno.bicudoComment #9
longwaveThanks, the new message is a good improvement.
Why don't we modify YamlFileLoader instead, then we only have to catch and throw once, in the same place as Symfony does?
Comment #10
bruno.bicudo@longwave the reporter (@joachim) said at the issue summary:
If you guys agree that
YamlFileLoaderis the best place to make the approach i can send another patch :)Comment #11
longwaveI think as Symfony's YamlFileLoader added this since we copied it, it's OK to put the same (or at least very similar) code in our copy too.
Comment #12
bruno.bicudoHere's a new patch with the proposed approach in
YamlFileLoader.I won't upload images this time as the messages remains the same.
Hope it helps. Will keep in "needs review", kindly review it and choose whichever fits the goal better :)
Comment #13
joachim commentedLooking good, just needs a few small fixes:
Local variable names should be camel case, not pascal.
That needs an initial backslash I think?
Typo: 'filea'.
Comment #14
bruno.bicudoOh my... Sorry for the typo there, i was in a hurry, my mistake.
Ok so:
#13-1: Pascal case would be like
$ValidFile, while camel case stands for$validFile, am i wrong? I think the variable name in this case is already camel case.#13-2:
InvalidDataTypeExceptiondoesn't need a backslash because it's already declared in an use statement under\Drupal\Component\Serialization\Exception\InvalidDataTypeException. Also thanks for pointing it, because i had used a backslash inInvalidArgumentExceptionwithout noticing it was also declared in an use statement XD#13-3: Corrected the typo, thanks for pointing it :D
New patch on it's way. Kindly review it :D
Comment #15
bruno.bicudoComment #16
joachim commented> #13-1: Pascal case would be like $ValidFile, while camel case stands for $validFile, am i wrong? I think the variable name in this case is already camel case.
Sorry, I was commenting too late at night :/
It should be snake case. Drupal coding standards say that local variables and function params are $snake_case.
Comment #17
bruno.bicudoNo problem haha.
This one fixes the variable name from camel case to snake case. Thanks for pointing it and for the clarification.
Kindly review it. :)
Comment #18
joachim commentedPerfect, thanks!
Comment #20
longwaveRandom fail, back to RTBC.
Comment #22
bruno.bicudoOnce again, random fail (retested it and passes). Yet, i'l leave it in needs review so that someone else checks it and moves to RTBC again if everything is ok :)
Comment #23
longwaveComment #25
longwaveYet another random fail in Quick Edit.
Comment #27
longwaveRandom fail in CKEditor.
Comment #29
ravi.shankar commentedBack to RTBC as per the above comments.
Comment #30
longwaveJust spotted that we need a space between
tryand{.Comment #31
_pratik_Comment #32
_pratik_Added spacing around try.
thanks
Comment #33
_pratik_Comment #35
maacl commentedTypo has been fixed, back to RTBC.
Comment #37
spokjeComment #38
xjmNice work. This is a solid bugfix.
We could provide ExpectedException test coverage for it as well. Is there a reason not to?
Comment #39
spokjeComment #41
joachim commentedHeredocs can now be indented with the surrounding code.
Comment #42
xjmhttps://www.drupal.org/pift-ci-job/2548777 also looks actually relevant.
Comment #43
joachim commentedThe 'qqq' line in the patch looks like stray test code (in the sense of 'work in progress/experimental', not unit tests) that should have been removed before rolling maybe?
Comment #44
spokjeDefinitely a case of "Last Patch of The Day"-syndrom.
Tried that locally, but it doesn't seem to work with indentation-sensitive code like YAML.
Comment #45
smustgrave commentedRan the test locally for #44 and it fails with
Tried breaking an existing service but could not but the test shows the issue just fine I believe.
Looks good!
Comment #46
catchIs this a case where we should be using assertions instead of exceptions? See for example #2454649: Cache Optimization and hardening -- [PP-1] Use assert() instead of exceptions in Cache::merge(Tags|Contexts). Since there are other similar exceptions in the same file, maybe a follow-up?
Comment #47
smustgrave commentedOpened #3339727: YamlFileLoader use assertions instead of exceptions
Comment #49
catchCommitted e53445e and pushed to 10.1.x. Thanks!