QmlDesigner: Trace project storage exceptions

Change-Id: I58c261bea4cca6c5bede0d2ad504be8bc687ddc6
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Marco Bubke
2024-03-18 12:23:42 +01:00
parent 99def2c337
commit 26870406cd
7 changed files with 170 additions and 35 deletions

View File

@@ -3,22 +3,6 @@
#include "projectstorage.h"
#include <tracing/qmldesignertracing.h>
#include <sqlitedatabase.h>
namespace QmlDesigner {
NanotraceHR::StringViewWithStringArgumentsCategory<projectStorageTracingStatus()> &projectStorageCategory()
{
thread_local NanotraceHR::StringViewWithStringArgumentsCategory<projectStorageTracingStatus()>
projectStorageCategory_{"project storage"_t,
Tracing::eventQueueWithStringArguments(),
projectStorageCategory};
return projectStorageCategory_;
}
} // namespace QmlDesigner
template class QmlDesigner::ProjectStorage<Sqlite::Database>;

View File

@@ -9,6 +9,8 @@
#include "sourcepathcachetypes.h"
#include "storagecache.h"
#include <tracing/qmldesignertracing.h>
#include <sqlitealgorithms.h>
#include <sqlitedatabase.h>
#include <sqlitetable.h>
@@ -28,17 +30,7 @@ namespace QmlDesigner {
using namespace NanotraceHR::Literals;
constexpr NanotraceHR::Tracing projectStorageTracingStatus()
{
#ifdef ENABLE_PROJECT_STORAGE_TRACING
return NanotraceHR::Tracing::IsEnabled;
#else
return NanotraceHR::Tracing::IsDisabled;
#endif
}
[[gnu::pure]] NanotraceHR::StringViewWithStringArgumentsCategory<projectStorageTracingStatus()> &
projectStorageCategory();
using ProjectStorageTracing::projectStorageCategory;
template<typename Database>
class ProjectStorage final : public ProjectStorageInterface

View File

@@ -3,38 +3,85 @@
#include "projectstorageexceptions.h"
#include <tracing/qmldesignertracing.h>
namespace QmlDesigner {
using namespace NanotraceHR::Literals;
using NanotraceHR::keyValue;
namespace {
auto &category()
{
return ProjectStorageTracing::projectStorageCategory();
}
} // namespace
NoSourcePathForInvalidSourceId::NoSourcePathForInvalidSourceId()
{
category().threadEvent("NoSourcePathForInvalidSourceId"_t);
}
const char *NoSourcePathForInvalidSourceId::what() const noexcept
{
return "You cannot get a file path for an invalid file path id!";
}
NoSourceContextPathForInvalidSourceContextId::NoSourceContextPathForInvalidSourceContextId()
{
category().threadEvent("NoSourceContextPathForInvalidSourceContextId"_t);
}
const char *NoSourceContextPathForInvalidSourceContextId::what() const noexcept
{
return "You cannot get a directory path for an invalid directory path id!";
}
SourceContextIdDoesNotExists::SourceContextIdDoesNotExists()
{
category().threadEvent("SourceContextIdDoesNotExists"_t);
}
const char *SourceContextIdDoesNotExists::what() const noexcept
{
return "The source context id does not exist in the database!";
}
SourceIdDoesNotExists::SourceIdDoesNotExists()
{
category().threadEvent("SourceIdDoesNotExists"_t);
}
const char *SourceIdDoesNotExists::what() const noexcept
{
return "The source id does not exist in the database!";
}
TypeHasInvalidSourceId::TypeHasInvalidSourceId()
{
category().threadEvent("TypeHasInvalidSourceId"_t);
}
const char *TypeHasInvalidSourceId::what() const noexcept
{
return "The source id is invalid!";
}
ModuleDoesNotExists::ModuleDoesNotExists()
{
category().threadEvent("ModuleDoesNotExists"_t);
}
const char *ModuleDoesNotExists::what() const noexcept
{
return "The module does not exist!";
}
ModuleAlreadyExists::ModuleAlreadyExists()
{
category().threadEvent("ModuleAlreadyExists"_t);
}
const char *ModuleAlreadyExists::what() const noexcept
{
return "The module does already exist!";
@@ -45,48 +92,97 @@ TypeNameDoesNotExists::TypeNameDoesNotExists(std::string_view typeName, SourceId
"TypeNameDoesNotExists"sv,
Utils::SmallString::join(
{"type: ", typeName, ", source id: ", Utils::SmallString::number(sourceId.internalId())})}
{}
{
category().threadEvent("TypeNameDoesNotExists"_t,
keyValue("type name", typeName),
keyValue("source id", sourceId));
}
PropertyNameDoesNotExists::PropertyNameDoesNotExists()
{
category().threadEvent("PropertyNameDoesNotExists"_t);
}
const char *PropertyNameDoesNotExists::what() const noexcept
{
return "The property name does not exist!";
}
PrototypeChainCycle::PrototypeChainCycle()
{
category().threadEvent("PrototypeChainCycle"_t);
}
const char *PrototypeChainCycle::what() const noexcept
{
return "There is a prototype chain cycle!";
}
AliasChainCycle::AliasChainCycle()
{
category().threadEvent("AliasChainCycle"_t);
}
const char *AliasChainCycle::what() const noexcept
{
return "There is a prototype chain cycle!";
}
CannotParseQmlTypesFile::CannotParseQmlTypesFile()
{
category().threadEvent("CannotParseQmlTypesFile"_t);
}
const char *CannotParseQmlTypesFile::what() const noexcept
{
return "Cannot parse qml types file!";
}
CannotParseQmlDocumentFile::CannotParseQmlDocumentFile()
{
category().threadEvent("CannotParseQmlDocumentFile"_t);
}
const char *CannotParseQmlDocumentFile::what() const noexcept
{
return "Cannot parse qml types file!";
}
ProjectDataHasInvalidProjectSourceId::ProjectDataHasInvalidProjectSourceId()
{
category().threadEvent("ProjectDataHasInvalidProjectSourceId"_t);
}
const char *ProjectDataHasInvalidProjectSourceId::what() const noexcept
{
return "The project source id is invalid!";
}
ProjectDataHasInvalidSourceId::ProjectDataHasInvalidSourceId()
{
category().threadEvent("ProjectDataHasInvalidSourceId"_t);
}
const char *ProjectDataHasInvalidSourceId::what() const noexcept
{
return "The source id is invalid!";
}
ProjectDataHasInvalidModuleId::ProjectDataHasInvalidModuleId()
{
category().threadEvent("ProjectDataHasInvalidModuleId"_t);
}
const char *ProjectDataHasInvalidModuleId::what() const noexcept
{
return "The module id is invalid!";
}
FileStatusHasInvalidSourceId::FileStatusHasInvalidSourceId()
{
category().threadEvent("FileStatusHasInvalidSourceId"_t);
}
const char *FileStatusHasInvalidSourceId::what() const noexcept
{
return "The source id in file status is invalid!";
@@ -113,7 +209,14 @@ const char *ProjectStorageErrorWithMessage::what() const noexcept
ExportedTypeCannotBeInserted::ExportedTypeCannotBeInserted(std::string_view errorMessage)
: ProjectStorageErrorWithMessage{"ExportedTypeCannotBeInserted"sv, errorMessage}
{}
{
category().threadEvent("ExportedTypeCannotBeInserted"_t, keyValue("error message", errorMessage));
}
TypeAnnotationHasInvalidSourceId::TypeAnnotationHasInvalidSourceId()
{
category().threadEvent("TypeAnnotationHasInvalidSourceId"_t);
}
const char *TypeAnnotationHasInvalidSourceId::what() const noexcept
{

View File

@@ -15,15 +15,19 @@ using namespace std::literals::string_view_literals;
class QMLDESIGNERCORE_EXPORT ProjectStorageError : public std::exception
{
protected:
ProjectStorageError() = default;
public:
const char *what() const noexcept override;
};
class ProjectStorageErrorWithMessage : public ProjectStorageError
{
public:
protected:
ProjectStorageErrorWithMessage(std::string_view error, std::string_view errorMessage);
public:
const char *what() const noexcept override;
public:
@@ -33,42 +37,49 @@ public:
class QMLDESIGNERCORE_EXPORT NoSourcePathForInvalidSourceId : public ProjectStorageError
{
public:
NoSourcePathForInvalidSourceId();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT NoSourceContextPathForInvalidSourceContextId : public ProjectStorageError
{
public:
NoSourceContextPathForInvalidSourceContextId();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT SourceContextIdDoesNotExists : public ProjectStorageError
{
public:
SourceContextIdDoesNotExists();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT SourceIdDoesNotExists : public ProjectStorageError
{
public:
SourceIdDoesNotExists();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT TypeHasInvalidSourceId : public ProjectStorageError
{
public:
TypeHasInvalidSourceId();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT ModuleDoesNotExists : public ProjectStorageError
{
public:
ModuleDoesNotExists();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT ModuleAlreadyExists : public ProjectStorageError
{
public:
ModuleAlreadyExists();
const char *what() const noexcept override;
};
@@ -87,60 +98,70 @@ public:
class QMLDESIGNERCORE_EXPORT PropertyNameDoesNotExists : public ProjectStorageError
{
public:
PropertyNameDoesNotExists();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT PrototypeChainCycle : public ProjectStorageError
{
public:
PrototypeChainCycle();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT AliasChainCycle : public ProjectStorageError
{
public:
AliasChainCycle();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT CannotParseQmlTypesFile : public ProjectStorageError
{
public:
CannotParseQmlTypesFile();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT CannotParseQmlDocumentFile : public ProjectStorageError
{
public:
CannotParseQmlDocumentFile();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT ProjectDataHasInvalidProjectSourceId : public ProjectStorageError
{
public:
ProjectDataHasInvalidProjectSourceId();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT ProjectDataHasInvalidSourceId : public ProjectStorageError
{
public:
ProjectDataHasInvalidSourceId();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT ProjectDataHasInvalidModuleId : public ProjectStorageError
{
public:
ProjectDataHasInvalidModuleId();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT FileStatusHasInvalidSourceId : public ProjectStorageError
{
public:
FileStatusHasInvalidSourceId();
const char *what() const noexcept override;
};
class QMLDESIGNERCORE_EXPORT TypeAnnotationHasInvalidSourceId : public ProjectStorageError
{
public:
TypeAnnotationHasInvalidSourceId();
const char *what() const noexcept override;
};

View File

@@ -6,6 +6,9 @@
#include <sqlitebasestatement.h>
namespace QmlDesigner {
using namespace NanotraceHR::Literals;
namespace Tracing {
namespace {
@@ -51,7 +54,6 @@ StringEventQueue &stringEventQueue()
namespace ModelTracing {
namespace {
using namespace NanotraceHR::Literals;
thread_local Category category_{"model"_t, Tracing::stringEventQueue(), category};
@@ -63,4 +65,19 @@ Category &category()
}
} // namespace ModelTracing
namespace ProjectStorageTracing {
NanotraceHR::StringViewWithStringArgumentsCategory<projectStorageTracingStatus()> &projectStorageCategory()
{
thread_local NanotraceHR::StringViewWithStringArgumentsCategory<projectStorageTracingStatus()>
projectStorageCategory_{"project storage"_t,
Tracing::eventQueueWithStringArguments(),
projectStorageCategory};
return projectStorageCategory_;
}
} // namespace ProjectStorageTracing
} // namespace QmlDesigner

View File

@@ -44,4 +44,18 @@ using AsynchronousToken = Category::AsynchronousTokenType;
[[gnu::pure]] QMLDESIGNERCORE_EXPORT Category &category();
} // namespace ModelTracing
namespace ProjectStorageTracing {
constexpr NanotraceHR::Tracing projectStorageTracingStatus()
{
#ifdef ENABLE_PROJECT_STORAGE_TRACING
return NanotraceHR::Tracing::IsEnabled;
#else
return NanotraceHR::Tracing::IsDisabled;
#endif
}
[[gnu::pure]] NanotraceHR::StringViewWithStringArgumentsCategory<projectStorageTracingStatus()> &
projectStorageCategory();
} // namespace ProjectStorageTracing
} // namespace QmlDesigner

View File

@@ -3210,7 +3210,8 @@ TEST_F(ProjectStorageUpdater, errors_for_watcher_updates_are_handled)
SecondType 2.2 Second.qml)"};
setContent(u"/path/qmldir", qmldir);
ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Throw(QmlDesigner::ProjectStorageError{}));
ON_CALL(projectStorageMock, synchronize(_))
.WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{}));
ASSERT_NO_THROW(updater.pathsWithIdsChanged({{directoryProjectChunkId, {directoryPathSourceId}}}));
}
@@ -3227,7 +3228,8 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens)
{{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes},
{directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}});
setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId});
ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Throw(QmlDesigner::ProjectStorageError{}));
ON_CALL(projectStorageMock, synchronize(_))
.WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{}));
updater.pathsWithIdsChanged(
{{qmltypesProjectChunkId, {qmltypesPathSourceId, qmltypes2PathSourceId}}});
ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Return());
@@ -3286,7 +3288,8 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens_and_
{{directoryPathSourceId, qmltypesPathSourceId, exampleModuleId, FileType::QmlTypes},
{directoryPathSourceId, qmltypes2PathSourceId, exampleModuleId, FileType::QmlTypes}});
setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId});
ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Throw(QmlDesigner::ProjectStorageError{}));
ON_CALL(projectStorageMock, synchronize(_))
.WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{}));
updater.pathsWithIdsChanged(
{{qmltypesProjectChunkId, {qmltypesPathSourceId, qmltypes2PathSourceId}}});
ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Return());
@@ -3348,7 +3351,8 @@ TEST_F(ProjectStorageUpdater, input_is_reused_next_call_if_an_error_happens_and_
{directoryPathSourceId, qmlDocumentSourceId1, QmlDesigner::ModuleId{}, FileType::QmlDocument},
{directoryPathSourceId, qmlDocumentSourceId1, QmlDesigner::ModuleId{}, FileType::QmlDocument}});
setFilesDontChanged({directoryPathSourceId, qmlDirPathSourceId});
ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Throw(QmlDesigner::ProjectStorageError{}));
ON_CALL(projectStorageMock, synchronize(_))
.WillByDefault(Throw(QmlDesigner::NoSourcePathForInvalidSourceId{}));
updater.pathsWithIdsChanged(
{{qmlDocumentProjectChunkId, {qmlDocumentSourceId1, qmlDocumentSourceId2}}});
ON_CALL(projectStorageMock, synchronize(_)).WillByDefault(Return());