From 8b272813541f230c8960b6ec7e4f430e3fc96c69 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Thu, 10 Mar 2022 15:11:33 +0200 Subject: [PATCH] QmlDesigner: Show error message on import log for failed 3D import The import is done on puppet side, so we use a log file to pass the error message. Also changed how import process is matched to the import, so that exit code is no longer needed for this purpose. Crashes are also now reported as import errors. Task-number: QDS-6402 Change-Id: Ie14cd1df0bbba965d8e5f2aa7302a955e944379b Reviewed-by: Samuel Ghinet Reviewed-by: Mahmoud Badri Reviewed-by: --- .../qml2puppet/import3d/import3d.cpp | 44 +++++++++++-------- .../qmlpuppet/qml2puppet/import3d/import3d.h | 2 +- .../qmlpuppet/qml2puppet/qml2puppetmain.cpp | 5 +-- .../itemlibrary/itemlibraryassetimporter.cpp | 39 ++++++++++++---- .../itemlibrary/itemlibraryassetimporter.h | 4 +- 5 files changed, 61 insertions(+), 33 deletions(-) diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.cpp index c1cbca6f5ee..5f448b90da5 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.cpp @@ -29,18 +29,21 @@ #include #endif +#include +#include +#include #include #include -#include -#include #include -#include +#include +#include namespace Import3D { -void import3D(const QString &sourceAsset, const QString &outDir, int exitId, const QString &options) +void import3D(const QString &sourceAsset, const QString &outDir, const QString &options) { + QString errorStr; #ifdef IMPORT_QUICK3D_ASSETS QScopedPointer importer {new QSSGAssetImportManager}; @@ -48,32 +51,35 @@ void import3D(const QString &sourceAsset, const QString &outDir, int exitId, con QJsonDocument optDoc = QJsonDocument::fromJson(options.toUtf8(), &error); if (!optDoc.isNull() && optDoc.isObject()) { - QString errorStr; QJsonObject optObj = optDoc.object(); if (importer->importFile(sourceAsset, outDir, optObj.toVariantMap(), &errorStr) != QSSGAssetImportManager::ImportState::Success) { - qWarning() << __FUNCTION__ << "Failed to import 3D asset" - << sourceAsset << "with error:" << errorStr; - } else { - // Allow little time for file operations to finish - QTimer::singleShot(2000, nullptr, [exitId]() { - qApp->exit(exitId); - }); - return; } } else { - qWarning() << __FUNCTION__ << "Failed to parse import options:" << error.errorString(); + errorStr = QObject::tr("Failed to parse import options: %1").arg(error.errorString()); } #else + errorStr = QObject::tr("QtQuick3D is not available."); Q_UNUSED(sourceAsset) Q_UNUSED(outDir) - Q_UNUSED(exitId) Q_UNUSED(options) - qWarning() << __FUNCTION__ << "Failed to parse import options, Quick3DAssetImport not available"; #endif - QTimer::singleShot(0, nullptr, [exitId]() { - // Negative exitId means import failure - qApp->exit(-exitId); + if (!errorStr.isEmpty()) { + qWarning() << __FUNCTION__ << "Failed to import asset:" << errorStr << outDir; + + // Write the error into a file in outDir to pass it to creator side + QString errorFileName = outDir + "/__error.log"; + QFile file(errorFileName); + if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { + QTextStream out(&file); + out << errorStr; + file.close(); + } + } + + // Allow little time for file operations to finish + QTimer::singleShot(2000, nullptr, []() { + qApp->exit(0); }); } diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.h b/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.h index eb2e4731724..3f53ef33c79 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.h +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/import3d/import3d.h @@ -29,5 +29,5 @@ namespace Import3D { - void import3D(const QString &sourceAsset, const QString &outDir, int id, const QString &options); + void import3D(const QString &sourceAsset, const QString &outDir, const QString &options); }; diff --git a/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp index 8b6135c6222..5a7e0d7dd8b 100644 --- a/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp +++ b/share/qtcreator/qml/qmlpuppet/qml2puppet/qml2puppetmain.cpp @@ -228,10 +228,9 @@ int internalMain(QGuiApplication *application) if (application->arguments().at(1) == "--import3dAsset") { QString sourceAsset = application->arguments().at(2); QString outDir = application->arguments().at(3); - int exitId = application->arguments().at(4).toInt(); - QString options = application->arguments().at(5); + QString options = application->arguments().at(4); - Import3D::import3D(sourceAsset, outDir, exitId, options); + Import3D::import3D(sourceAsset, outDir, options); return application->exec(); } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp index 1ff31aad632..7e22efe016f 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.cpp @@ -142,9 +142,10 @@ void ItemLibraryAssetImporter::addInfo(const QString &infoMsg, const QString &sr emit infoReported(infoMsg, srcPath); } -void ItemLibraryAssetImporter::importProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) +void ItemLibraryAssetImporter::importProcessFinished(int exitCode, QProcess::ExitStatus exitStatus, + int importId) { - Q_UNUSED(exitStatus) + Q_UNUSED(exitCode) ++m_qmlImportFinishedCount; @@ -154,9 +155,32 @@ void ItemLibraryAssetImporter::importProcessFinished(int exitCode, QProcess::Exi return !entry || entry->state() == QProcess::NotRunning; })); - if (m_parseData.contains(-exitCode)) { - const ParseData pd = m_parseData.take(-exitCode); - addError(tr("Asset import process failed for: \"%1\".").arg(pd.sourceInfo.absoluteFilePath())); + if (m_parseData.contains(importId)) { + const ParseData &pd = m_parseData[importId]; + QString errStr; + if (exitStatus == QProcess::ExitStatus::CrashExit) { + errStr = tr("Import process crashed."); + } else { + bool unknownFail = !pd.outDir.exists() || pd.outDir.isEmpty(); + if (!unknownFail) { + QFile errorLog(pd.outDir.filePath("__error.log")); + if (errorLog.exists()) { + if (errorLog.open(QIODevice::ReadOnly)) + errStr = QString::fromUtf8(errorLog.readAll()); + else + unknownFail = true; + } + } + if (unknownFail) + errStr = tr("Import failed for unknown reason."); + } + + if (!errStr.isEmpty()) { + addError(tr("Asset import process failed: \"%1\".") + .arg(pd.sourceInfo.absoluteFilePath())); + addError(errStr); + m_parseData.remove(importId); + } } if (m_qmlImportFinishedCount == m_qmlPuppetCount) { @@ -565,15 +589,14 @@ bool ItemLibraryAssetImporter::startImportProcess(const ParseData &pd) QJsonDocument optDoc(pd.options); puppetArgs << "--import3dAsset" << pd.sourceInfo.absoluteFilePath() - << pd.outDir.absolutePath() << QString::number(pd.importId) - << QString::fromUtf8(optDoc.toJson()); + << pd.outDir.absolutePath() << QString::fromUtf8(optDoc.toJson()); QProcessUniquePointer process = puppetCreator.createPuppetProcess( "custom", {}, [&] {}, [&](int exitCode, QProcess::ExitStatus exitStatus) { - importProcessFinished(exitCode, exitStatus); + importProcessFinished(exitCode, exitStatus, pd.importId); }, puppetArgs); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h index 9abc315fbe0..83be9af5f4e 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimporter.h @@ -74,7 +74,7 @@ signals: void importFinished(); private slots: - void importProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); + void importProcessFinished(int exitCode, QProcess::ExitStatus exitStatus, int importId); void iconProcessFinished(int exitCode, QProcess::ExitStatus exitStatus); private: @@ -125,7 +125,7 @@ private: std::vector m_qmlPuppetProcesses; int m_qmlPuppetCount = 0; int m_qmlImportFinishedCount = 0; - int m_importIdCounter = 1000000; // Use ids in range unlikely to clash with any normal process exit codes + int m_importIdCounter = 0; QHash m_parseData; QString m_progressTitle; QList m_requiredImports;