feat: opt-in error reporting
This commit is contained in:
parent
00f30a6495
commit
544e5a68dc
5 changed files with 46 additions and 0 deletions
|
@ -131,6 +131,18 @@ export interface BaseTelegramClientOptions {
|
|||
*/
|
||||
disableUpdates?: boolean
|
||||
|
||||
/**
|
||||
* mtcute can send all unknown RPC errors to [danog](https://github.com/danog)'s
|
||||
* [error reporting service](https://rpc.pwrtelegram.xyz/).
|
||||
*
|
||||
* This is fully anonymous (except maybe IP) and is only used to improve the library
|
||||
* and developer experience for everyone working with MTProto. This is fully opt-in,
|
||||
* and if you're too paranoid, you can disable it by manually passing `enableErrorReporting: false` to the client.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
enableErrorReporting?: boolean
|
||||
|
||||
/**
|
||||
* If true, RPC errors will have a stack trace of the initial `.call()`
|
||||
* or `.sendForResult()` call position, which drastically improves
|
||||
|
@ -288,6 +300,7 @@ export class BaseTelegramClient extends EventEmitter {
|
|||
isPremium: false,
|
||||
useIpv6: Boolean(opts.useIpv6),
|
||||
keepAliveAction: this._keepAliveAction.bind(this),
|
||||
enableErrorReporting: opts.enableErrorReporting ?? false,
|
||||
...(opts.network ?? {}),
|
||||
},
|
||||
this._config,
|
||||
|
|
|
@ -33,6 +33,7 @@ export interface NetworkManagerParams {
|
|||
crypto: ICryptoProvider
|
||||
log: Logger
|
||||
|
||||
enableErrorReporting: boolean
|
||||
apiId: number
|
||||
initConnectionOptions?: Partial<Omit<tl.RawInitConnectionRequest, 'apiId' | 'query'>>
|
||||
transport?: TransportFactory
|
||||
|
@ -156,6 +157,7 @@ export class DcConnectionManager {
|
|||
isMainConnection: false,
|
||||
isMainDcConnection: this.isPrimary,
|
||||
inactivityTimeout: this.manager.params.inactivityTimeout ?? 60_000,
|
||||
enableErrorReporting: this.manager.params.enableErrorReporting,
|
||||
})
|
||||
|
||||
private _log = this.manager._log.create('dc-manager')
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
removeFromLongArray,
|
||||
} from '../utils'
|
||||
import { createAesIgeForMessageOld } from '../utils/crypto/mtproto'
|
||||
import { reportUnknownError } from '../utils/platform/error-reporting'
|
||||
import { doAuthorization } from './authorization'
|
||||
import { MtprotoSession, PendingMessage, PendingRpc } from './mtproto-session'
|
||||
import { PersistentConnection, PersistentConnectionParams } from './persistent-connection'
|
||||
|
@ -29,6 +30,7 @@ export interface SessionConnectionParams extends PersistentConnectionParams {
|
|||
initConnection: tl.RawInitConnectionRequest
|
||||
inactivityTimeout?: number
|
||||
niceStacks?: boolean
|
||||
enableErrorReporting: boolean
|
||||
layer: number
|
||||
disableUpdates?: boolean
|
||||
withUpdates?: boolean
|
||||
|
@ -760,6 +762,10 @@ export class SessionConnection extends PersistentConnection {
|
|||
makeNiceStack(error, rpc.stack!, rpc.method)
|
||||
}
|
||||
|
||||
if (error.unknown && this.params.enableErrorReporting) {
|
||||
reportUnknownError(this.log, error, rpc.method)
|
||||
}
|
||||
|
||||
rpc.promise.reject(error)
|
||||
} else {
|
||||
this.log.debug('received rpc_result (%s) for request %l (%s)', result._, reqMsgId, rpc.method)
|
||||
|
|
23
packages/core/src/utils/platform/error-reporting.ts
Normal file
23
packages/core/src/utils/platform/error-reporting.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { Logger } from '../logger'
|
||||
|
||||
export function reportUnknownError(log: Logger, error: tl.RpcError, method: string): void {
|
||||
if (typeof fetch !== 'function') return
|
||||
|
||||
fetch(`https://rpc.pwrtelegram.xyz/?code=${error.code}&method=${method}&error=${error.text}`)
|
||||
.then((r) => r.json())
|
||||
.then((r) => {
|
||||
if (r.ok) {
|
||||
log.info('telerpc responded with error info for %s: %s', error.text, r.result)
|
||||
} else {
|
||||
log.info(
|
||||
'Reported error %s to telerpc. You can disable this using `enableErrorReporting: false`',
|
||||
error.text,
|
||||
)
|
||||
}
|
||||
})
|
||||
.catch((e) => {
|
||||
log.debug('failed to report error %s to telerpc: %s', error.text, e)
|
||||
})
|
||||
}
|
|
@ -8,6 +8,7 @@ class RpcError extends Error {
|
|||
super(_descriptionsMap[text] || 'Unknown RPC error: [' + code + ':' + text + ']');
|
||||
this.code = code;
|
||||
this.text = text;
|
||||
this.unknown = !_descriptionsMap[text];
|
||||
}
|
||||
|
||||
static is(err, text) { return err.constructor === RpcError && (!text || err.text === text); }
|
||||
|
@ -44,6 +45,7 @@ export class RpcError extends Error {
|
|||
|
||||
readonly code: number;
|
||||
readonly text: MtErrorText;
|
||||
readonly unknown: boolean;
|
||||
constructor(code: number, text: MtErrorText);
|
||||
|
||||
is<const T extends MtErrorText>(text: T): this is RpcErrorWithArgs<T>;
|
||||
|
|
Loading…
Reference in a new issue