feat(core): handle AUTH_KEY_UNREGISTERED error

This commit is contained in:
teidesu 2021-06-05 18:56:43 +03:00
parent 79af4c4425
commit 68ea4080df
2 changed files with 48 additions and 16 deletions

View file

@ -86,21 +86,21 @@ export async function* downloadAsIterable(
const requestCurrent = async (): Promise<Buffer> => { const requestCurrent = async (): Promise<Buffer> => {
let result: tl.RpcCallReturn['upload.getFile'] | tl.RpcCallReturn['upload.getWebFile'] let result: tl.RpcCallReturn['upload.getFile'] | tl.RpcCallReturn['upload.getWebFile']
try { try {
result = await connection.sendForResult({ result = await this.call({
_: isWeb ? 'upload.getWebFile' : 'upload.getFile', _: isWeb ? 'upload.getWebFile' : 'upload.getFile',
location: location as any, location: location as any,
offset, offset,
limit: chunkSize limit: chunkSize
}) }, { connection })
} catch (e) { } catch (e) {
if (e instanceof FileMigrateError) { if (e.constructor === FileMigrateError) {
connection = this._downloadConnections[e.newDc] connection = this._downloadConnections[e.newDc]
if (!connection) { if (!connection) {
connection = await this.createAdditionalConnection(e.newDc) connection = await this.createAdditionalConnection(e.newDc)
this._downloadConnections[e.newDc] = connection this._downloadConnections[e.newDc] = connection
} }
return requestCurrent() return requestCurrent()
} else if (e instanceof FilerefUpgradeNeededError) { } else if (e.constructor === FilerefUpgradeNeededError) {
// todo: implement someday // todo: implement someday
// see: https://github.com/LonamiWebs/Telethon/blob/0e8bd8248cc649637b7c392616887c50986427a0/telethon/client/downloads.py#L99 // see: https://github.com/LonamiWebs/Telethon/blob/0e8bd8248cc649637b7c392616887c50986427a0/telethon/client/downloads.py#L99
throw new MtCuteUnsupportedError('File ref expired!') throw new MtCuteUnsupportedError('File ref expired!')

View file

@ -17,6 +17,7 @@ import {
defaultProductionIpv6Dc, defaultProductionIpv6Dc,
} from './utils/default-dcs' } from './utils/default-dcs'
import { import {
AuthKeyUnregisteredError,
FloodTestPhoneWaitError, FloodTestPhoneWaitError,
FloodWaitError, FloodWaitError,
InternalError, InternalError,
@ -347,7 +348,9 @@ export class BaseTelegramClient {
this.storage.setAuthKeyFor(this._primaryDc.id, key) this.storage.setAuthKeyFor(this._primaryDc.id, key)
await this._saveStorage() await this._saveStorage()
}) })
this.primaryConnection.on('error', (err) => this._emitError(err, this.primaryConnection)) this.primaryConnection.on('error', (err) =>
this._emitError(err, this.primaryConnection)
)
} }
/** /**
@ -488,7 +491,11 @@ export class BaseTelegramClient {
for (let i = 0; i < this._rpcRetryCount; i++) { for (let i = 0; i < this._rpcRetryCount; i++) {
try { try {
const res = await connection.sendForResult(message, stack, params?.timeout) const res = await connection.sendForResult(
message,
stack,
params?.timeout
)
await this._cachePeersFrom(res) await this._cachePeersFrom(res)
return res return res
@ -530,16 +537,37 @@ export class BaseTelegramClient {
continue continue
} }
} }
if (connection.params.dc.id === this._primaryDc.id) {
if ( if (
connection === this.primaryConnection && e.constructor === PhoneMigrateError ||
(e.constructor === PhoneMigrateError ||
e.constructor === UserMigrateError || e.constructor === UserMigrateError ||
e.constructor === NetworkMigrateError) e.constructor === NetworkMigrateError
) { ) {
debug('Migrate error, new dc = %d', e.newDc) debug('Migrate error, new dc = %d', e.newDc)
await this.changeDc(e.newDc) await this.changeDc(e.newDc)
continue continue
} }
} else {
if (e.constructor === AuthKeyUnregisteredError) {
// we can try re-exporting auth from the primary connection
debug('exported auth key error, re-exporting..')
const auth = await this.call({
_: 'auth.exportAuthorization',
dcId: connection.params.dc.id,
})
await connection.sendForResult({
_: 'auth.importAuthorization',
id: auth.id,
bytes: auth.bytes,
})
continue
}
}
throw e throw e
} }
} }
@ -635,7 +663,9 @@ export class BaseTelegramClient {
changeTransport(factory: TransportFactory): void { changeTransport(factory: TransportFactory): void {
this.primaryConnection.changeTransport(factory) this.primaryConnection.changeTransport(factory)
this._additionalConnections.forEach((conn) => conn.changeTransport(factory)) this._additionalConnections.forEach((conn) =>
conn.changeTransport(factory)
)
} }
/** /**
@ -647,7 +677,9 @@ export class BaseTelegramClient {
* the connection in which the error has occurred, in case * the connection in which the error has occurred, in case
* this was connection-related error. * this was connection-related error.
*/ */
onError(handler: (err: Error, connection?: TelegramConnection) => void): void { onError(
handler: (err: Error, connection?: TelegramConnection) => void
): void {
this._onError = handler this._onError = handler
} }