Couchbase\Exception: LCB_KEY_ENOENT

When i try to get a document that does not exist in on the server via $res = $bucket->get("$myNbr"); the system throws an exception error. Is there a pretty way to handle this ? i would like to go, get the doc and if the key(doc) does not exist just do something in my php code like

if (success)
{
    echo $res;
}
else
{
    echo 'Could not find data';
}

i was able to use the try Catch way but it seems to be pretty ugly to handle a simple no records found. On that topic where can i find a list of errror codes , 13 seems to be equal of LCB_KEY_ENOENT

try{
       $res = $bucket->get("$myNbr");
       var_dump($res->value);
    }
    catch(\Exception $e) {
    echo $e->getCode();
}

You can use COUCHBASE_KEY_ENOENT constant to check the error code

And I must say that we have plans to improve error handing in upcoming releases. Cleaning up exceptions is one of the goals, to avoid forcing to use exceptions in control flow like in your example.

Thanks for the error codes but i take it there is no other clean way to check if the document exists other then using the try and catch. I saw some other sdk’s have better support in handling that type
of issues and coming from mysql and the relational world, if i try to get a row which doesn’t exist i do a simple check if i have data or get my rowcount and act on that not the ugly exception way

Subdocument operations do not raise exceptions because when you query multiple paths, one of them might generate error, while others not. In this case result will have error code COUCHBASE_SUBDOC_MULTI_FAILURE

<?php
$cluster = new \Couchbase\Cluster("couchbase://localhost");
$bucket = $cluster->openBucket('default');

$bucket->upsert('foo', ['path1' => 'value1']);

$result = $bucket->retrieveIn('does-not-exist', 'any-path');
if ($result->error->getCode() == COUCHBASE_KEY_ENOENT) {
   echo "\$result->error->getCode() == COUCHBASE_KEY_ENOENT\n";
}

$result = $bucket->retrieveIn('foo', 'any-path');
if ($result->error->getCode() == COUCHBASE_SUBDOC_MULTI_FAILURE) {
  echo "\$result->error->getCode() == COUCHBASE_SUBDOC_MULTI_FAILURE\n";
  if ($result->value[0]['code'] == COUCHBASE_SUBDOC_PATH_ENOENT) {
    echo "\$result->value[0]['code'] == COUCHBASE_SUBDOC_PATH_ENOENT\n";
  }
}

So you can build your own exception-free “exists()” wrapper, based on subdoc.

I saw there is support for subdocs but how about ic I want to get complete doc
should this work ?

$result= $bucket->get("$myNbr");
if ($result->error->getCode() == COUCHBASE_KEY_ENOENT) {
  echo 'doc not found';
}

no, this one will raise exception when document does not exist.

Is there any plan to make this a bit more consistent like exposing the same function to get->doc as you have for subdoc ?
I also read that there was talk about providing similar to the .net implementation something like this
if(!result.Success && result.Exception != null)

yes. we do have this in our list

Hm… PHP SDK 2.6
end of 2021.
Exceptions are still thrown when trying to get a complete document.
In what decade are you planning to return false if there is no document in the storage?
2030? 2040?

hi avsej,
we are also getting same exception , dba checked the same document is preset on bucket but application end they are getting below error. could you help me if you experienced on this type of errors. just want to understand why this is behaving like this.

{“date”:“2023-10-03T22:34:37.904441111+09:00”,“lvl”:“ER”,“tid”:“1”,“host”:“”,“srv”:“”,“file”:“rohandler/api.handleCRDLRoutines/handler.go:1248”,“pid”:“9”,“traceid”:“UAT_Call_CDR_Import_07089159962_20231003181300_1015”,“msg”:“[[sessionid: Exit- Error in handleCRDLRoutines: document not found | {"status_code":1,"document_id":"Line-Bal::262021500849454 ","bucket":"billing","scope":"_default","collection":"_default","error_name":"KEY_ENOENT","error_description":"Not Found","opaque":28,"last_dispatched_to":"[<…>:2:7:b06]:11210","last_dispatched_from":"[<…>:9af]:47092","last_connection_id":"2a1d84c7bc3ca569/df5b82d89b127c65"}]]”}

From the error message output, it appears that the document_id specified has trailing white-space. Try removing the trailing white-space. Or check that the document_id in couchbase has the same trailing white-space.

Also note that the document_id specified in kv APIs is the meta-data id. It is the value used on the insert(id, doc) or upsert(id, doc) operations. It is NOT a property in the document named “id” (or “document_id”).

If you are sure that it is the same document_id in the request and in couchbase - check that the bucket name matches, the scope name matches and the collection name matches. Also check that the client is connected to the couchbase cluster that contains the document.

1 Like