{"record":{"id":"e4d0a2b29d31cbd7","repo":"nextcloud/server","slug":"e-getmessage-e4d0a2","errorCode":null,"errorMessage":"$e->getMessage()","messagePattern":"\\$e->getMessage\\(\\)","errorType":"exception","errorClass":"Sabre\\DAV\\Exception","httpStatus":500,"severity":"error","filePath":"apps/dav/lib/Connector/Sabre/File.php","lineNumber":645,"sourceCode":"\t\tif ($e instanceof LockedException || $e instanceof LockNotAcquiredException) {\n\t\t\t// the file is currently being written to by another process\n\t\t\tthrow new FileLocked($e->getMessage(), $e->getCode(), $e);\n\t\t}\n\t\tif ($e instanceof GenericEncryptionException) {\n\t\t\t// returning 503 will allow retry of the operation at a later point in time\n\t\t\tthrow new ServiceUnavailable($this->l10n->t('Encryption not ready: %1$s', [$e->getMessage()]), 0, $e);\n\t\t}\n\t\tif ($e instanceof StorageNotAvailableException) {\n\t\t\tthrow new ServiceUnavailable($this->l10n->t('Failed to write file contents: %1$s', [$e->getMessage()]), 0, $e);\n\t\t}\n\t\tif ($e instanceof NotFoundException) {\n\t\t\tthrow new NotFound($this->l10n->t('File not found: %1$s', [$e->getMessage()]), 0, $e);\n\t\t}\n\t\tif ($e instanceof NotEnoughSpaceException) {\n\t\t\tthrow new EntityTooLarge($this->l10n->t('Insufficient space'), 0, $e);\n\t\t}\n\n\t\tthrow new \\Sabre\\DAV\\Exception($e->getMessage(), 0, $e);\n\t}\n\n\t/**\n\t * Get the checksum for this file\n\t *\n\t * @return string|null\n\t */\n\tpublic function getChecksum() {\n\t\treturn $this->info->getChecksum();\n\t}\n\n\tpublic function setChecksum(string $checksum) {\n\t\t$this->fileView->putFileInfo($this->path, ['checksum' => $checksum]);\n\t\t$this->refreshInfo();\n\t}\n\n\tprotected function header($string) {\n\t\tif (!\\OC::$CLI) {","sourceCodeStart":627,"sourceCodeEnd":663,"githubUrl":"https://github.com/nextcloud/server/blob/ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3/apps/dav/lib/Connector/Sabre/File.php#L627-L663","documentation":"This is the catch-all branch of OCA\\DAV\\Connector\\Sabre\\File::convertToSabreException() (apps/dav/lib/Connector/Sabre/File.php:645). Every exception raised while writing a file through the DAV connector (PUT, chunked upload, MOVE-overwrite) is passed here and mapped to a Sabre DAV exception; anything that is not NotPermitted, Forbidden, EntityTooLarge, InvalidContent, InvalidPath, Locked, GenericEncryption, StorageNotAvailable, NotFound or NotEnoughSpace falls through to a bare \\Sabre\\DAV\\Exception carrying the original message. Since \\Sabre\\DAV\\Exception maps to HTTP 500, this error always means an unmapped, unexpected server-side failure during a file write.","triggerScenarios":"A WebDAV PUT (or chunked-upload MOVE/assemble) where the underlying OC\\Files storage or an app hook throws an exception type not listed in convertToSabreException(): e.g. a custom storage backend throwing a domain-specific exception, a post-write hook (OC\\Files\\hook or an Event) throwing, or a database error surfacing as \\OCP\\DbException or \\Doctrine\\DBALException during cache update.","commonSituations":"Third-party external-storage drivers that throw their own exception classes instead of OCP\\Files exceptions; encryption or antivirus app hooks failing mid-write; transient database failures; running apps that are incompatible with the server version and throw inside filesystem hooks; object-store (S3/Swift) SDK exceptions leaking through.","solutions":["Check the Nextcloud log (data/nextcloud.log or admin Settings > Log): the wrapped exception is chained as $e->getPrevious(), and its class name and stack trace identify the real failing component.","If the previous exception comes from a custom storage backend or app, fix or update that app/backend so it throws the documented OCP\\Files\\* exceptions (StorageNotAvailableException, NotFoundException, ...) which are mapped to proper HTTP codes.","If you maintain server code, add a mapping branch in convertToSabreException() for the recurring exception type instead of letting it fall through to a 500.","If the underlying error is a DB/outage problem, resolve the outage and retry the upload; clients should treat HTTP 500 on PUT as retryable with backoff."],"exampleFix":"// before (custom storage throws \\MyVendor\\S3SdkException during put())\n//   -> surfaces as: \\Sabre\\DAV\\Exception(\"cURL error 28 ...\") -> HTTP 500\n\n// after (in the custom storage, translate to a mapped exception)\ntry {\n    $this->s3Client->putObject($params);\n} catch (\\MyVendor\\S3SdkException $e) {\n    throw new \\OCP\\Files\\StorageNotAvailableException($e->getMessage(), 0, $e);\n    // now converts to 503 ServiceUnavailable so clients retry instead of failing hard\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    $file->put($stream); // or writeFileHandle\n} catch (\\Sabre\\DAV\\Exception $e) {\n    $cause = $e->getPrevious();\n    if ($cause instanceof \\OCP\\Files\\StorageNotAvailableException) {\n        // retry later / surface 503 semantics\n    }\n    \\OC::$server->getLogger()->error('DAV write failed: ' . get_class($cause), ['exception' => $e]);\n    throw $e;\n}","preventionTips":["Log the chained previous exception — the outer message alone never identifies the component.","Storage backends should throw the OCP\\Files\\* exception types so they map to correct HTTP codes instead of 500.","Clients should retry HTTP 500 on PUT with backoff only a limited number of times.","Keep apps that hook into file writes compatible with the current server version."],"tags":["dav","file-upload","sabre","exception-conversion","http-500"],"backgroundTag":"file-write-failed","analyzedSha":"ecdeb153ffdf227235c9a7e2d13dbe0f9c817bc3","analyzedAt":"2026-08-17T01:36:13.386Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}