| 9 | #include "net/ApiDownload.h" |
| 10 | |
| 11 | Task::Ptr ResourceAPI::searchProjects(SearchArgs&& args, Callback<QList<ModPlatform::IndexedPack::Ptr>>&& callbacks) const |
| 12 | { |
| 13 | auto search_url_optional = getSearchURL(args); |
| 14 | if (!search_url_optional.has_value()) { |
| 15 | callbacks.on_fail("Failed to create search URL", -1); |
| 16 | return nullptr; |
| 17 | } |
| 18 | |
| 19 | auto search_url = search_url_optional.value(); |
| 20 | |
| 21 | auto netJob = makeShared<NetJob>(QString("%1::Search").arg(debugName()), APPLICATION->network()); |
| 22 | |
| 23 | auto [action, response] = Net::ApiDownload::makeByteArray(QUrl(search_url)); |
| 24 | netJob->addNetAction(action); |
| 25 | |
| 26 | QObject::connect(netJob.get(), &NetJob::succeeded, [this, response, callbacks] { |
| 27 | QJsonParseError parse_error{}; |
| 28 | QJsonDocument doc = QJsonDocument::fromJson(*response, &parse_error); |
| 29 | if (parse_error.error != QJsonParseError::NoError) { |
| 30 | qWarning() << "Error while parsing JSON response from" << debugName() << "at" << parse_error.offset |
| 31 | << "reason:" << parse_error.errorString(); |
| 32 | qWarning() << *response; |
| 33 | |
| 34 | callbacks.on_fail(parse_error.errorString(), -1); |
| 35 | |
| 36 | return; |
| 37 | } |
| 38 | |
| 39 | QList<ModPlatform::IndexedPack::Ptr> newList; |
| 40 | auto packs = documentToArray(doc); |
| 41 | |
| 42 | for (auto packRaw : packs) { |
| 43 | auto packObj = packRaw.toObject(); |
| 44 | |
| 45 | ModPlatform::IndexedPack::Ptr pack = std::make_shared<ModPlatform::IndexedPack>(); |
| 46 | try { |
| 47 | loadIndexedPack(*pack, packObj); |
| 48 | newList << pack; |
| 49 | } catch (const JSONValidationError& e) { |
| 50 | qWarning().nospace() << "Error while loading resource from " << debugName() << ": " << e.cause(); |
| 51 | continue; |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | callbacks.on_succeed(newList); |
| 56 | }); |
| 57 | |
| 58 | // Capture a weak_ptr instead of a shared_ptr to avoid circular dependency issues. |
| 59 | // This prevents the lambda from extending the lifetime of the shared resource, |
| 60 | // as it only temporarily locks the resource when needed. |
| 61 | auto weak = netJob.toWeakRef(); |
| 62 | QObject::connect(netJob.get(), &NetJob::failed, [weak, callbacks](const QString& reason) { |
| 63 | int network_error_code = -1; |
| 64 | if (auto netJob = weak.lock()) { |
| 65 | if (auto* failed_action = netJob->getFailedActions().at(0); failed_action) |
| 66 | network_error_code = failed_action->replyStatusCode(); |
| 67 | } |
| 68 | callbacks.on_fail(reason, network_error_code); |
no test coverage detected