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

Add more details to FileManager error report #1895

Merged
merged 28 commits into from
Nov 30, 2024
Merged
Show file tree
Hide file tree
Changes from 24 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
741a56d
Fix case where saving with no undo changes would fail
MrStevns Nov 22, 2024
0d9bf8a
QMiniz: Simplify logic
MrStevns Nov 22, 2024
871ccc9
QMiniz: Make sure to abort when failing to compress file
MrStevns Nov 22, 2024
33115d4
Improve the error detail log for readability
MrStevns Nov 22, 2024
466f6be
ErrorDialog: Add copy to clipboard
MrStevns Nov 22, 2024
335d88d
Improve error details for readability - take 2
MrStevns Nov 23, 2024
422cce5
Improve error details for readability - take 3
MrStevns Nov 23, 2024
8b705f8
Write a note when a backup has been made
MrStevns Nov 23, 2024
30397b2
FileManager: Fix logic does not account for existing backup files
MrStevns Nov 23, 2024
e106ac5
Improve layer saving diagnostics
MrStevns Nov 23, 2024
93fd589
Fix where where project couldn't be saved because miniz tried to zip …
MrStevns Nov 23, 2024
fb0b24e
Improve diagnostics around qminiz and archiving
MrStevns Nov 23, 2024
afa857f
Add text explaining the importance of the bug report
MrStevns Nov 23, 2024
05b0381
Add missing space
MrStevns Nov 23, 2024
dcd70c5
QMiniz: make sure to always close reader
MrStevns Nov 23, 2024
09deac9
Layer: Add error diagnostics when failing to save one or more layers
MrStevns Nov 23, 2024
66034b3
FileManager:writeMainXML: Slightly safer way to close file
MrStevns Nov 23, 2024
566ae76
QMiniz: Make errors more explicit and fail quickly.
MrStevns Nov 24, 2024
33eed04
Add error keyword to writePalette
MrStevns Nov 24, 2024
b511d5d
FileManager: close file after recovery.
MrStevns Nov 24, 2024
93e8213
Remove indentation
MrStevns Nov 24, 2024
8480697
FileManager: Check for Unzipping errors
MrStevns Nov 24, 2024
3447d67
QMiniz: Fix typo...
MrStevns Nov 24, 2024
d4bdc23
Add missing QFile::close where a file has been opened.
MrStevns Nov 24, 2024
87007c5
ErrorDialog: shorten description
MrStevns Nov 28, 2024
85b43e6
QMiniz: Only close if we succeded to open it
MrStevns Nov 28, 2024
685f96f
Remove explicit file.close because QFile already handles this
MrStevns Nov 29, 2024
055dd7f
Fix relative include path
MrStevns Nov 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/src/errordialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ GNU General Public License for more details.
#include "errordialog.h"
#include "ui_errordialog.h"

#include <QPushButton>
#include <QClipboard>

ErrorDialog::ErrorDialog( QString title, QString description, QString details, QWidget *parent ) :
QDialog( parent ),
ui(new Ui::ErrorDialog)
Expand All @@ -34,9 +37,18 @@ ErrorDialog::ErrorDialog( QString title, QString description, QString details, Q
{
ui->details->setText( QString( "<pre>%1</pre>" ).arg( details ) );
}

QPushButton* copyToClipboard = new QPushButton(tr("Copy to Clipboard"));
ui->buttonBox->addButton(copyToClipboard, QDialogButtonBox::ActionRole);

connect(copyToClipboard, &QPushButton::clicked, this, &ErrorDialog::onCopyToClipboard);
}

ErrorDialog::~ErrorDialog()
{
delete ui;
}

void ErrorDialog::onCopyToClipboard() {
QGuiApplication::clipboard()->setText(ui->details->toPlainText());
}
3 changes: 3 additions & 0 deletions app/src/errordialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ class ErrorDialog : public QDialog
explicit ErrorDialog(QString title, QString description, QString details = QString(), QWidget *parent = nullptr);
~ErrorDialog();

public slots:
void onCopyToClipboard();

private:
Ui::ErrorDialog *ui;
};
Expand Down
2 changes: 1 addition & 1 deletion app/src/mainwindow2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -773,7 +773,7 @@ bool MainWindow2::saveObject(QString strSavedFileName)

ErrorDialog errorDialog(st.title(),
st.description().append(tr("<br><br>An error has occurred and your file may not have saved successfully."
"If you believe that this error is an issue with Pencil2D, please create a new issue at:"
"\nIf you believe that this error is an issue with Pencil2D, please create a new issue at:"
"<br><a href='https://github.com/pencil2d/pencil/issues'>https://github.com/pencil2d/pencil/issues</a><br>"
"Please be sure to include the following details in your issue:")), st.details().html());
errorDialog.exec();
Expand Down
10 changes: 10 additions & 0 deletions app/ui/errordialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>The following report contains vital information to figure out the cause of the error. Make sure to copy all of it, if you intend to report the bug.</string>
MrStevns marked this conversation as resolved.
Show resolved Hide resolved
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QTextEdit" name="details">
<property name="readOnly">
Expand Down
9 changes: 7 additions & 2 deletions core_lib/src/graphics/bitmap/bitmapimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -742,9 +742,14 @@ Status BitmapImage::writeFile(const QString& filename)
if(f.exists())
{
bool b = f.remove();
return (b) ? Status::OK : Status::FAIL;
if (!b) {
return Status::FAIL;
}
}
return Status::SAFE;

// The frame is likely empty, act like there's no file name
// so we don't end up writing to it later.
setFileName("");
}
return Status::SAFE;
}
Expand Down
7 changes: 7 additions & 0 deletions core_lib/src/graphics/vector/vectorimage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ GNU General Public License for more details.
#include <QDebug>
#include <QXmlStreamWriter>
#include "object.h"
#include "util.h"


VectorImage::VectorImage()
Expand Down Expand Up @@ -82,6 +83,9 @@ bool VectorImage::read(QString filePath)
{
return false;
}
ScopeGuard fileScope([&] {
file.close();
});
MrStevns marked this conversation as resolved.
Show resolved Hide resolved

QDomDocument doc;
if (!doc.setContent(&file)) return false; // this is not a XML file
Expand Down Expand Up @@ -123,6 +127,9 @@ Status VectorImage::write(QString filePath, QString format)
debugInfo << ("file.error() = " + file.errorString());
return Status(Status::FAIL, debugInfo);
}
ScopeGuard fileScope([&] {
file.close();
});

if (format != "VEC")
{
Expand Down
2 changes: 1 addition & 1 deletion core_lib/src/managers/undoredomanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Status UndoRedoManager::save(Object* /*o*/)
{
if (mNewBackupSystemEnabled) {
mUndoStack.setClean();
} else {
} else if (!mLegacyBackupList.isEmpty() && mLegacyBackupIndex < mLegacyBackupList.count()) {
mLegacyBackupAtSave = mLegacyBackupList[mLegacyBackupIndex];
}
return Status::OK;
Expand Down
66 changes: 32 additions & 34 deletions core_lib/src/qminiz.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,13 @@ Status MiniZ::sanityCheck(const QString& sZipFilePath)

if (!readOk || !closeOk) {
DebugDetails dd;

dd << "\n[Miniz sanity check]\n";
if (read_err != MZ_ZIP_NO_ERROR) {
dd << QString("Miniz found an error while reading the file. - %1, %2").arg(static_cast<int>(read_err)).arg(mz_zip_get_error_string(read_err));
dd << QString("Found an error while reading the file. Error code: %2, reason: %3").arg(static_cast<int>(read_err)).arg(mz_zip_get_error_string(read_err));
}
if (close_err != MZ_ZIP_NO_ERROR) {
dd << QString("Miniz found an error while closing file file. - %1, %2").arg(static_cast<int>(close_err)).arg(mz_zip_get_error_string(close_err));
dd << QString("Found an error while closing the file. Error code: %2, reason: %3").arg(static_cast<int>(close_err)).arg(mz_zip_get_error_string(close_err));
}
return Status(Status::ERROR_MINIZ_FAIL, dd);
}
Expand All @@ -66,27 +68,32 @@ size_t MiniZ::istreamReadCallback(void *pOpaque, mz_uint64 file_ofs, void * pBuf
Status MiniZ::compressFolder(QString zipFilePath, QString srcFolderPath, const QStringList& fileList, QString mimetype)
{
DebugDetails dd;
dd << "\n[Miniz COMPRESSION diagnostics]\n";
dd << QString("Creating Zip %1 from folder %2").arg(zipFilePath, srcFolderPath);

if (!srcFolderPath.endsWith("/"))
{
dd << "Adding / to path";
srcFolderPath.append("/");
}

mz_zip_archive* mz = new mz_zip_archive;
ScopeGuard mzScopeGuard([&] {
Copy link
Member

Choose a reason for hiding this comment

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

OnScopeExit(delete mz);

Copy link
Member Author

Choose a reason for hiding this comment

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

I knew about OnScopeExit when I made this change, I just prefer using ScopeGuard directly rather than a macro

delete mz;
});

mz_zip_zero_struct(mz);

mz_bool ok = mz_zip_writer_init_file(mz, zipFilePath.toUtf8().data(), 0);

ScopeGuard mzScopeGuard([&] {
ScopeGuard mzScopeGuard2([&] {
mz_zip_writer_end(mz);
delete mz;
});

if (!ok)
{
mz_zip_error err = mz_zip_get_last_error(mz);
dd << QString("Miniz writer init failed: error %1, %2").arg(static_cast<int>(err)).arg(mz_zip_get_error_string(err));
dd << QString("Error: Failed to init writer. Error code: %1, reason: %2").arg(static_cast<int>(err)).arg(mz_zip_get_error_string(err));
return Status(Status::FAIL, dd);
}

// Add special uncompressed mimetype file to help with the identification of projects
Expand All @@ -99,7 +106,8 @@ Status MiniZ::compressFolder(QString zipFilePath, QString srcFolderPath, const Q
if (!ok)
{
mz_zip_error err = mz_zip_get_last_error(mz);
dd << QString("Cannot add mimetype: error %1").arg(static_cast<int>(err)).arg(mz_zip_get_error_string(err));
dd << QString("ERROR: Unable to add mimetype. Error code: %1, reason: %2").arg(static_cast<int>(err)).arg(mz_zip_get_error_string(err));
return Status(Status::FAIL, dd);
}
}

Expand All @@ -119,26 +127,15 @@ Status MiniZ::compressFolder(QString zipFilePath, QString srcFolderPath, const Q
if (!ok)
{
mz_zip_error err = mz_zip_get_last_error(mz);
dd << QString("Cannot add %3: error %1, %2").arg(static_cast<int>(err)).arg(mz_zip_get_error_string(err), sRelativePath);
dd << QString("Error: Unable to add file: %3. Error code: %1, reason: %2 - Aborting!").arg(static_cast<int>(err)).arg(mz_zip_get_error_string(err), sRelativePath);
return Status(Status::FAIL, dd);
}
}
ok &= mz_zip_writer_finalize_archive(mz);
if (!ok)
{
mz_zip_error err = mz_zip_get_last_error(mz);
dd << QString("Miniz finalize archive failed: error %1, %2").arg(static_cast<int>(err)).arg(mz_zip_get_error_string(err));
return Status(Status::FAIL, dd);
}

ok &= mz_zip_writer_end(mz);

mzScopeGuard.dismiss();
ScopeGuard mzScopeGuard2([&] { delete mz; });

if (!ok)
{
mz_zip_error err = mz_zip_get_last_error(mz);
dd << QString("Miniz writer end failed: error %1, %2").arg(static_cast<int>(err)).arg(mz_zip_get_error_string(err));
dd << QString("Error: Failed to finalize archive. Error code %1, reason: %2").arg(static_cast<int>(err)).arg(mz_zip_get_error_string(err));
return Status(Status::FAIL, dd);
}

Expand All @@ -148,10 +145,12 @@ Status MiniZ::compressFolder(QString zipFilePath, QString srcFolderPath, const Q
Status MiniZ::uncompressFolder(QString zipFilePath, QString destPath)
{
DebugDetails dd;
dd << "\n[Miniz EXTRACTION diagnostics]\n";
dd << QString("Unzip file %1 to folder %2").arg(zipFilePath, destPath);

if (!QFile::exists(zipFilePath))
{
dd << QString("Error: Zip file does not exist.");
return Status::FILE_NOT_FOUND;
}

Expand All @@ -166,17 +165,22 @@ Status MiniZ::uncompressFolder(QString zipFilePath, QString destPath)
baseDir.makeAbsolute();

mz_zip_archive* mz = new mz_zip_archive;
ScopeGuard mzScopeGuard([&] {
delete mz;
});

mz_zip_zero_struct(mz);

mz_bool ok = mz_zip_reader_init_file(mz, zipFilePath.toUtf8().data(), 0);

ScopeGuard mzScopeGuard([&] {
ScopeGuard mzScopeGuard2([&] {
MrStevns marked this conversation as resolved.
Show resolved Hide resolved
mz_zip_reader_end(mz);
delete mz;
});

if (!ok)
if (!ok) {
mz_zip_error err = mz_zip_get_last_error(mz);
dd << QString("Error: Failed to init reader. Error code: %1, reason: %2").arg(static_cast<int>(err)).arg(mz_zip_get_error_string(err));
return Status(Status::FAIL, dd);
}

int num = mz_zip_reader_get_num_files(mz);

Expand Down Expand Up @@ -215,21 +219,15 @@ Status MiniZ::uncompressFolder(QString zipFilePath, QString destPath)
if (!extractOK)
{
ok = false;
dd << "File extraction failed.";
mz_zip_error err = mz_zip_get_last_error(mz);
dd << QString("WARNING: Unable to extract file. Error code: %1, reason: %2").arg(static_cast<int>(err)).arg(mz_zip_get_error_string(err));
}
}
}

ok &= mz_zip_reader_end(mz);

mzScopeGuard.dismiss();
ScopeGuard mzScopeGuard2([&] {
delete mz;
});

if (!ok)
{
dd << "Unzip error!";
return Status(Status::FAIL, dd);
}
return Status::OK;
}
5 changes: 5 additions & 0 deletions core_lib/src/soundplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ GNU General Public License for more details.
#include <QMediaPlayer>
#include <QFile>
#include "soundclip.h"
#include "util.h"

SoundPlayer::SoundPlayer()
{
Expand All @@ -41,6 +42,10 @@ void SoundPlayer::init(SoundClip* clip)

QFile file(clip->fileName());
file.open(QIODevice::ReadOnly);
ScopeGuard fileScope([&] {
file.close();
MrStevns marked this conversation as resolved.
Show resolved Hide resolved
});


mBuffer.setData(file.readAll());
mBuffer.open(QBuffer::ReadOnly);
Expand Down
Loading
Loading