mirror of
https://github.com/wiz0u/WTelegramClient.git
synced 2025-12-06 06:52:01 +01:00
Provide X number (if any) and generic message in RpcException. Retry only once on -503 error.
This commit is contained in:
parent
e6a1dbb24d
commit
796b49546e
2
.github/dev.yml
vendored
2
.github/dev.yml
vendored
|
|
@ -2,7 +2,7 @@ pr: none
|
|||
trigger:
|
||||
- master
|
||||
|
||||
name: 2.2.2-dev.$(Rev:r)
|
||||
name: 2.3.1-dev.$(Rev:r)
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
|
|
|
|||
2
.github/release.yml
vendored
2
.github/release.yml
vendored
|
|
@ -1,7 +1,7 @@
|
|||
pr: none
|
||||
trigger: none
|
||||
|
||||
name: 2.2.$(Rev:r)
|
||||
name: 2.3.$(Rev:r)
|
||||
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
|
|
|
|||
|
|
@ -362,10 +362,9 @@ namespace WTelegram
|
|||
{
|
||||
fileBase = await client.Upload_GetFile(fileLocation, offset, FilePartSize);
|
||||
}
|
||||
catch (RpcException ex) when (ex.Code == 303 && ex.Message.StartsWith("FILE_MIGRATE_"))
|
||||
catch (RpcException ex) when (ex.Code == 303 && ex.Message == "FILE_MIGRATE_X")
|
||||
{
|
||||
var dcId = int.Parse(ex.Message[13..]);
|
||||
client = await GetClientForDC(dcId, true);
|
||||
client = await GetClientForDC(ex.X, true);
|
||||
fileBase = await client.Upload_GetFile(fileLocation, offset, FilePartSize);
|
||||
}
|
||||
catch (RpcException ex) when (ex.Code == 400 && ex.Message == "OFFSET_INVALID")
|
||||
|
|
|
|||
|
|
@ -1088,41 +1088,40 @@ namespace WTelegram
|
|||
}
|
||||
}
|
||||
|
||||
internal async Task<X> InvokeBare<X>(IMethod<X> request)
|
||||
internal async Task<T> InvokeBare<T>(IMethod<T> request)
|
||||
{
|
||||
if (_bareRpc != null) throw new ApplicationException("A bare request is already undergoing");
|
||||
_bareRpc = new Rpc { type = typeof(X) };
|
||||
_bareRpc = new Rpc { type = typeof(T) };
|
||||
await SendAsync(request, false, _bareRpc);
|
||||
return (X)await _bareRpc.Task;
|
||||
return (T)await _bareRpc.Task;
|
||||
}
|
||||
|
||||
/// <summary>Call the given TL method <i>(You shouldn't need to use this method directly)</i></summary>
|
||||
/// <typeparam name="X">Expected type of the returned object</typeparam>
|
||||
/// <typeparam name="T">Expected type of the returned object</typeparam>
|
||||
/// <param name="query">TL method structure</param>
|
||||
/// <returns>Wait for the reply and return the resulting object, or throws an RpcException if an error was replied</returns>
|
||||
public async Task<X> Invoke<X>(IMethod<X> query)
|
||||
public async Task<T> Invoke<T>(IMethod<T> query)
|
||||
{
|
||||
retry:
|
||||
var rpc = new Rpc { type = typeof(X) };
|
||||
await SendAsync(query, true, rpc);
|
||||
bool got503 = false;
|
||||
retry:
|
||||
var rpc = new Rpc { type = typeof(T) };
|
||||
await SendAsync(query, true, rpc);
|
||||
var result = await rpc.Task;
|
||||
switch (result)
|
||||
{
|
||||
case X resultX: return resultX;
|
||||
case T resultT: return resultT;
|
||||
case RpcError rpcError:
|
||||
int number;
|
||||
if (rpcError.error_code == 303 && ((number = rpcError.error_message.IndexOf("_MIGRATE_")) > 0))
|
||||
var x = rpcError.ParseX();
|
||||
if (rpcError.error_code == 303 && rpcError.error_message.EndsWith("_MIGRATE_X"))
|
||||
{
|
||||
if (!rpcError.error_message.StartsWith("FILE_"))
|
||||
if (rpcError.error_message != "FILE_MIGRATE_X")
|
||||
{
|
||||
number = int.Parse(rpcError.error_message[(number + 9)..]);
|
||||
// this is a hack to migrate _dcSession in-place (staying in same Client):
|
||||
Session.DCSession dcSession;
|
||||
lock (_session)
|
||||
dcSession = GetOrCreateDCSession(number, _dcSession.DataCenter.flags);
|
||||
dcSession = GetOrCreateDCSession(x, _dcSession.DataCenter.flags);
|
||||
Reset(false, false);
|
||||
_session.MainDC = number;
|
||||
_session.MainDC = x;
|
||||
_dcSession.Client = null;
|
||||
_dcSession = dcSession;
|
||||
_dcSession.Client = this;
|
||||
|
|
@ -1130,12 +1129,11 @@ namespace WTelegram
|
|||
goto retry;
|
||||
}
|
||||
}
|
||||
else if (rpcError.error_code == 420 && ((number = rpcError.error_message.IndexOf("_WAIT_")) > 0))
|
||||
else if (rpcError.error_code == 420 && rpcError.error_message.EndsWith("_WAIT_X"))
|
||||
{
|
||||
number = int.Parse(rpcError.error_message[(number + 6)..]);
|
||||
if (number <= FloodRetryThreshold)
|
||||
if (x <= FloodRetryThreshold)
|
||||
{
|
||||
await Task.Delay(number * 1000);
|
||||
await Task.Delay(x * 1000);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
|
@ -1149,11 +1147,11 @@ namespace WTelegram
|
|||
_session.UserId = 0; // force a full login authorization flow, next time
|
||||
lock (_session) _session.Save();
|
||||
}
|
||||
throw new RpcException(rpcError.error_code, rpcError.error_message);
|
||||
throw new RpcException(rpcError.error_code, rpcError.error_message, x);
|
||||
case ReactorError:
|
||||
goto retry;
|
||||
default:
|
||||
throw new ApplicationException($"{query.GetType().Name} call got a result of type {result.GetType().Name} instead of {typeof(X).Name}");
|
||||
throw new ApplicationException($"{query.GetType().Name} call got a result of type {result.GetType().Name} instead of {typeof(T).Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,6 @@ namespace TL
|
|||
|
||||
/// <summary>Accumulate users/chats found in this structure in your dictionaries, ignoring <see href="https://core.telegram.org/api/min">Min constructors</see> when the full object is already stored</summary>
|
||||
/// <param name="structure">The structure having a <c>users</c></param>
|
||||
/// <param name="users"></param>
|
||||
/// <param name="chats"></param>
|
||||
public static void CollectUsersChats(this IPeerResolver structure, Dictionary<long, User> users, Dictionary<long, ChatBase> chats)
|
||||
=> structure.UserOrChat(new CollectorPeer { _users = users, _chats = chats });
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,6 +198,22 @@ namespace TL
|
|||
{
|
||||
public int error_code;
|
||||
public string error_message;
|
||||
|
||||
public int ParseX() // ⚠ Method replace number in error_message with a X
|
||||
{
|
||||
for (int index = error_message.Length - 1; index > 0 && (index = error_message.LastIndexOf('_', index - 1)) >= 0;)
|
||||
{
|
||||
if (error_message[index + 1] is >= '0' and <= '9')
|
||||
{
|
||||
int end = ++index;
|
||||
do end++; while (end < error_message.Length && error_message[end] is >= '0' and <= '9');
|
||||
var x = int.Parse(error_message[index..end]);
|
||||
error_message = $"{error_message[0..index]}X{error_message[end..]}";
|
||||
return x;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class RpcDropAnswer : IObject { }
|
||||
|
|
|
|||
|
|
@ -31,7 +31,9 @@ namespace TL
|
|||
public class RpcException : Exception
|
||||
{
|
||||
public readonly int Code;
|
||||
public RpcException(int code, string message) : base(message) => Code = code;
|
||||
/// <summary>The value of X in the message, -1 if no variable X was found</summary>
|
||||
public readonly int X;
|
||||
public RpcException(int code, string message, int x = -1) : base(message) { Code = code; X = x; }
|
||||
public override string ToString() { var str = base.ToString(); return str.Insert(str.IndexOf(':') + 1, " " + Code); }
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue