Closed devonuto closed 2 years ago
Hm, according to the stacktrace, it looks like qBittorrent tries to call an abstract method somewhere in their code. So it seems to be their bug. But I can try to investigate this issue too.
Do you know which library method or API call causes this crash?
Unfortunately it's impossible to tell as it doesn't trigger an error in my code which I can capture, and only seems to happen when called from the qBitTorrent application itself. Error doesn't ever seem to occur when stepping through.
I can tell you that these are the only methods I use (tried both API versions 1 and 2):
`using (QBittorrentClient qBitClient = new QBittorrentClient(new Uri("http://192.168.1.2:8080/"))) { try { await qBitClient.LoginAsync(Globals.TorrentUser, Globals.TorrentPw); } catch { return; }
foreach (TorrentInfo torrent in qBitClient.GetTorrentListAsync().Result)
{
if (torrent.Progress < 1)
{
continue;
}
// Check if all pieces downloaded successfully.
IReadOnlyList<TorrentPieceState> pieces = await qBitClient.GetTorrentPiecesStatesAsync(torrent.Hash);
if (pieces.Any(piece => piece.ToString() != "Downloaded"))
{
await qBitClient.RecheckAsync(new List<string> {torrent.Hash});
continue;
}
foreach (TorrentContent file in qBitClient.GetTorrentContentsAsync(torrent.Hash).Result)
{
// Do stuff
}
await qBitClient.PauseAsync(torrent.Hash);
// Other calls made
await qBitClient.ResumeAsync(torrent.Hash);
await qBitClient.DeleteAsync(torrent.Hash, true)
}
await qBitClient.LogoutAsync();
qBitClient.Dispose();
}`
Ok, I can see some issues with your code.
The main issue, is that you use RecheckAsync
for the incompleted torrent. The purpose of this method is to check, whether the completed torrent was correctly downloaded. It calculates the hash of each downloaded part and compares it with the hash stored in the .torrent file. If the hash of some part is incorrect, qBittorrent will redownload it. So it is likely that there is a bug in qBittorrent that causes it crash if you try to recheck the incompleted torrent.
I would also recommend against using Task.Result
property (e.g. qBitClient.GetTorrentListAsync().Result
) as it can cause deadlocks in some case. You can use await qBitClient.GetTorrentListAsync()
instead.
If you explain a little bit more what you want to achieve, I can probably help you.
I did have the call to check if progress is completed:
if (torrent.Progress < 1) { continue; }
before calling the GetTorrentPiecesStatesAsync. I have moved the paused call on the torrent to above that code, and using await calls. I'll see how that goes.
Tried the above still crashing. Going to try removing the pieces check altogether and see if that helps.
Managed to capture an exception on
IReadOnlyList<TorrentInfo> torrents = await qBitClient.GetTorrentListAsync(); bool hasTorrent = torrents.Count > 0;
EXCEPTION: System.InvalidCastException: Unable to cast object of type 'System.Numerics.BigInteger' to type 'System.IConvertible'. at System.Convert.ToInt64(Object value) at QBittorrent.Client.Converters.SecondsToTimeSpanConverter.ReadJson(JsonReader reader, Type objectType, Object existingValue, JsonSerializer serializer) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.DeserializeConvertable(JsonConverter converter, JsonReader reader, Type objectType, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings) at QBittorrent.Client.QBittorrentClient.<>c__DisplayClass22_0.<gExecuteAsync|0>d.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at ProcessTorrents.ProcessTorrents.d13.MoveNext() EXCEPTION INNER EXCEPTION:
Though it is not the crash of qBittorrent itself, it still looks interesting. Probably, qBittorrent team has broken API compatibility once again. I will investigate it.
I wonder if this is possibly caused by the new Newtonsoft.json (12.0.2)
Don't use this anymore
I have an application that uses this package, and if I call the external application on torrent completion, qBittorrent crashes. However if I run it on a schedule, it doesn't seem to.
Not sure if the bug is on the package side, or the web interface of qBitTorrent.
This is the error I get (qBittorrent claim it's not their fault...):
qBittorrent version: v4.1.8 (64-bit) Libtorrent version: 1.1.13.0 Qt version: 5.13.1 Boost version: 1.71.0 OS version: Windows 10 (10.0) 10.0.17134 x86_64
Caught signal: SIGABRT