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

Handle 404 in CardDAV multi get #830

Closed
wants to merge 1 commit into from

Conversation

DeepDiver1975
Copy link
Member

refs #829

@DeepDiver1975
Copy link
Member Author

@evert ready to go from my pov - let me know what you think - THX

@DeepDiver1975
Copy link
Member Author

I'll take care about CalDAV multiget once we agree on this being the right way to do it

}
} catch (NotFound $ex) {
$result[$path] = [
404 => [],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about this response status. This tells me that the path is found, but it had 0 properties.

So two ideas:

  1. Set $result[$path] = null for items that are not found.
  2. Add a new status property to every item in $result, indicating the "overall" status of the thing on that path.

Either works for me, just null is a good indicator that the thing didn't exist and makes it very obvious, whereas adding a status would allow us to handle errors other than 404's in the future.

@DeepDiver1975 DeepDiver1975 force-pushed the multiget-404 branch 2 times, most recently from 8aab1fe to 583610a Compare July 7, 2016 10:23
@DeepDiver1975
Copy link
Member Author

@evert please have a look - THX

$writer->writeElement('{DAV:}status', 'HTTP/1.1 ' . $status . ' ' . \Sabre\HTTP\Response::$statusCodes[$status]);
// in case of a 404 we simply don't expect any properties at all
$empty = ($status !== 404);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I don't like this line. Could it get removed?

I don't think realistically that there might be a case where there's a resource-level 404 status, where we're returning properties anyway, but I don't really see a reason to special-case this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't set empty to true we will get a propset with 418/teapot inside. Kind of strange to me.

@evert
Copy link
Member

evert commented Jul 7, 2016

Great patch otherwise 👍

@@ -137,7 +139,6 @@ function xmlSerialize(Writer $writer) {
$writer->writeElement('{DAV:}prop', $properties);
$writer->writeElement('{DAV:}status', 'HTTP/1.1 ' . $status . ' ' . \Sabre\HTTP\Response::$statusCodes[$status]);
$writer->endElement(); // {DAV:}propstat

}
if ($empty) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DeepDiver1975 ah then this block really should be $empty && !$status all along. Preferably this function should be rewritten a bit so there's no duplication in writing the status element.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

poor coding on my side. Might have been drunk. Would explain the teapot

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have some more 🍺

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one Test here which expects an explicit status of 200 and an teaport propset.

I'll post it in a bit.

Copy link
Member Author

@DeepDiver1975 DeepDiver1975 Jul 8, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There was 1 failure:

1) Sabre\DAVACL\PrincipalMatchTest::testPrincipalMatch
Failed asserting that two DOM documents are equal.
--- Expected
+++ Actual
@@ @@
 <?xml version="1.0"?>
 <d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">
   <d:status>HTTP/1.1 200 OK</d:status>
   <d:href>/principals/user1</d:href>
-  <d:propstat>
-    <d:prop/>
-    <d:status>HTTP/1.1 418 I'm a teapot</d:status>
-  </d:propstat>
 </d:multistatus>

@DeepDiver1975
Copy link
Member Author

There was 1 failure:

1) Sabre\DAVACL\PrincipalMatchTest::testPrincipalMatch

Failed asserting that two DOM documents are equal.

--- Expected

+++ Actual

@@ @@

 <?xml version="1.0"?>

 <d:multistatus xmlns:d="DAV:" xmlns:s="http://sabredav.org/ns">

   <d:status>HTTP/1.1 200 OK</d:status>

   <d:href>/principals/user1</d:href>

-  <d:propstat>

-    <d:prop/>

-    <d:status>HTTP/1.1 418 I'm a teapot</d:status>

-  </d:propstat>

 </d:multistatus>

/home/travis/build/fruux/sabre-dav/tests/Sabre/DAVACL/PrincipalMatchTest.php:41

@DeepDiver1975
Copy link
Member Author

@evert Can I drag your attention onto this one?

@evert
Copy link
Member

evert commented Jul 22, 2016

Hey @DeepDiver1975 ,

I think i made a mistake conflating the inner propfind status (418 in your failing testcase) with the outer one. Sorry about that :( Fairly sure your original patch was good.

I suppose once the code is fixed so that unittest passes again we're good here. Sorry for all the wait.

@DeepDiver1975
Copy link
Member Author

@evert all green now - please have a second look. THX

@@ -994,20 +995,25 @@ function getPropertiesForMultiplePaths(array $paths, array $propertyNames = [])
$result = [
];

$nodes = $this->tree->getMultipleNodes($paths);
foreach ($paths as $path) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm super sorry for not spotting this issue earlier. I'm not as focused as I used to... but I see a new problem :(

The new problem with this patch, that I didn't see before, is that you're now no longer using getMultipleNodes(). While this solves the problem, the new problem is that that function was actually implemented to solve a fairly large performance problem.

There's several requests (such as sync-collection and multiget reports) that need to do a lot of individual lookups, and by adding the "Multiple" interfaces, new optimizations were possible.

So what can be done? I think the best thing is that getMultipleNodes actually gets changed to catch errors. The simplest solution there would be to omit (or return null) for the paths that throw a NotFound.

Then any non-NotFound exceptions will still 'fatal' though, so if we handle those as well in this patch we need a different mechanism. Perhaps the result of getMultipleNodes could return either a Node or an instance of Exception in case there was a problem? That would at least give us all the information (although it's a bit unconventional).

Sorry again :/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants