-
-
Notifications
You must be signed in to change notification settings - Fork 78
Throw specific exceptions from Manager::addBookFromPathAndGetId #1267
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
base: main
Are you sure you want to change the base?
Changes from all commits
ad577ac
b15c637
7c8a2a9
2201069
2f6d872
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| #pragma once | ||
|
|
||
| #include <exception> | ||
|
|
||
| namespace kiwix { | ||
|
|
||
|
Comment on lines
+1
to
+6
|
||
| class KiwixError : public std::exception { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| public: | ||
| const char* what() const noexcept override { | ||
| return "Kiwix error"; | ||
| } | ||
| }; | ||
|
|
||
| class FileNotFound : public KiwixError { | ||
| public: | ||
| const char* what() const noexcept override { | ||
| return "ZIM file not found"; | ||
| } | ||
|
Comment on lines
+16
to
+18
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't restrict this error to ZIM-files. Also an error message should be more informative, in this case knowing the path of the file in question would help (this applies to other errors in this commit too). |
||
| }; | ||
|
|
||
| class PermissionDenied : public KiwixError { | ||
| public: | ||
| const char* what() const noexcept override { | ||
| return "Permission denied while accessing ZIM file"; | ||
| } | ||
| }; | ||
|
Comment on lines
+21
to
+26
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should be renamed to |
||
|
|
||
| class InvalidZim : public KiwixError { | ||
| public: | ||
| const char* what() const noexcept override { | ||
| return "Invalid ZIM file"; | ||
| } | ||
| }; | ||
|
|
||
| class LibraryNotWritable : public KiwixError { | ||
| public: | ||
| const char* what() const noexcept override { | ||
| return "Library file is not writable"; | ||
| } | ||
| }; | ||
|
Comment on lines
+35
to
+40
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please rename this to |
||
|
|
||
| } // namespace kiwix | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -18,6 +18,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| #include "manager.h" | ||||||||||||||||||||||||||||||||||||||||||||||
| #include "kiwix/Error.h" | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| #include "tools.h" | ||||||||||||||||||||||||||||||||||||||||||||||
| #include "tools/pathTools.h" | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -209,36 +210,44 @@ bool Manager::readFile( | |||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| /* Add a book to the library. Return empty string if failed, book id otherwise | ||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||
| std::string Manager::addBookFromPathAndGetId(const std::string& pathToOpen, | ||||||||||||||||||||||||||||||||||||||||||||||
| const std::string& pathToSave, | ||||||||||||||||||||||||||||||||||||||||||||||
| const std::string& url, | ||||||||||||||||||||||||||||||||||||||||||||||
| const bool checkMetaData) | ||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||
| kiwix::Book book; | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| if (this->readBookFromPath(pathToOpen, &book)) { | ||||||||||||||||||||||||||||||||||||||||||||||
| if (!pathToSave.empty() && pathToSave != pathToOpen) { | ||||||||||||||||||||||||||||||||||||||||||||||
| book.setPath(isRelativePath(pathToSave) | ||||||||||||||||||||||||||||||||||||||||||||||
| ? computeAbsolutePath( | ||||||||||||||||||||||||||||||||||||||||||||||
| removeLastPathElement(writableLibraryPath), | ||||||||||||||||||||||||||||||||||||||||||||||
| pathToSave) | ||||||||||||||||||||||||||||||||||||||||||||||
| : pathToSave); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
| if (!this->readBookFromPath(pathToOpen, &book)) { | ||||||||||||||||||||||||||||||||||||||||||||||
| throw kiwix::FileNotFound(); | ||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+220
to
+222
|
||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+220
to
223
|
||||||||||||||||||||||||||||||||||||||||||||||
| if (!this->readBookFromPath(pathToOpen, &book)) { | |
| throw kiwix::FileNotFound(); | |
| } | |
| // Distinguish between missing files, permission issues, and invalid/corrupt ZIMs. | |
| if (!fileExists(pathToOpen)) { | |
| throw kiwix::FileNotFound(); | |
| } | |
| if (!fileReadable(pathToOpen)) { | |
| throw kiwix::PermissionDenied(); | |
| } | |
| if (!this->readBookFromPath(pathToOpen, &book)) { | |
| // The file exists and is readable, so a failure here most likely | |
| // indicates an invalid or corrupt ZIM archive. | |
| throw kiwix::InvalidZim(); | |
| } |
Copilot
AI
Jan 27, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LibraryManipulator::addBookToLibrary() is a simple wrapper returning bool and does not throw in normal operation (see same file, LibraryManipulator::addBookToLibrary). Catching ... here is likely ineffective and can also hide unrelated exceptions (e.g. allocation errors) by rethrowing LibraryNotWritable. Prefer removing the catch, or catching only the specific exception type(s) that represent a write failure and preserving the original error context.
| try { | |
| manipulator.addBookToLibrary(book); | |
| } catch (...) { | |
| throw kiwix::LibraryNotWritable(); | |
| } | |
| return book.getId(); | |
| } | |
| /* Wrapper over Manager::addBookFromPath which return a bool instead of a string | |
| manipulator.addBookToLibrary(book); | |
| return book.getId(); | |
| } | |
| /* Wrapper over Manager::addBookFromPath which return a bool instead of a string | |
| } | |
| /* Wrapper over Manager::addBookFromPath which return a bool instead of a string |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include "../include/tools.h" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <iostream> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <fstream> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <kiwix/Error.h> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TEST(ManagerTest, addBookFromPathAndGetIdTest) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -108,3 +109,44 @@ TEST(Manager, reload) | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "raycharles_uncategorized" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TEST(ManagerTest, addBookFromPathThrowsOnMissingFile) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto lib = kiwix::Library::create(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kiwix::Manager manager(lib); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EXPECT_THROW( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| manager.addBookFromPathAndGetId( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "/this/path/does/not/exist.zim", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| false | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kiwix::FileNotFound | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+118
to
+126
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| TEST(ManagerTest, addBookFromPathThrowsOnInvalidZim) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto lib = kiwix::Library::create(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kiwix::Manager manager(lib); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const std::string fakeZim = "not_a_real_zim.zim"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Create a fake file that is NOT a valid ZIM | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::ofstream out(fakeZim); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| out << "this is not a zim file"; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| out.close(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EXPECT_THROW( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| manager.addBookFromPathAndGetId( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fakeZim, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| kiwix::InvalidZim | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+128
to
+148
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have you run this test? I don't think that it should pass. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::remove(fakeZim.c_str()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const std::string fakeZim = "not_a_real_zim.zim"; | |
| // Create a fake file that is NOT a valid ZIM | |
| std::ofstream out(fakeZim); | |
| out << "this is not a zim file"; | |
| out.close(); | |
| EXPECT_THROW( | |
| manager.addBookFromPathAndGetId( | |
| fakeZim, | |
| "", | |
| "", | |
| true | |
| ), | |
| kiwix::InvalidZim | |
| ); | |
| std::remove(fakeZim.c_str()); | |
| // Use a ZIM file that exists but is invalid due to missing/invalid metadata. | |
| const std::string invalidZimPath = "./test/poor.zim"; | |
| EXPECT_THROW( | |
| manager.addBookFromPathAndGetId( | |
| invalidZimPath, | |
| "", | |
| "", | |
| true | |
| ), | |
| kiwix::InvalidZim | |
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All error situations should be tested. If they are difficult to test, it's OK to start with a limited number of error situations that we detect and add other error types later. All code that is written should be covered by tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This header is placed under
include/kiwix/, but the Meson install list ininclude/meson.buildcurrently installs only the top-level headers. As a result,<kiwix/Error.h>is likely not installed/packaged for downstream consumers. Update the build install rules to install this new public header (e.g. add it toinclude/meson.buildor add an additionalinstall_headers()call).