1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- const fs = require('fs')
- const csvParse = require('csv-parse/lib/sync')
- const { snakeToCamelCase, variableSnakeToCamelCase } = require('../utils')
- const KNOWN_BASE_CLASSES = {
- 303: 'InvalidDCError',
- 400: 'BadRequestError',
- 401: 'UnauthorizedError',
- 403: 'ForbiddenError',
- 404: 'NotFoundError',
- 406: 'AuthKeyError',
- 420: 'FloodError',
- 500: 'ServerError',
- 503: 'TimedOutError',
- }
- /**
- * Gets the corresponding class name for the given error code,
- * this either being an integer (thus base error name) or str.
- */
- const getClassName = (errorCode) => {
- if (typeof errorCode === 'number') {
- return KNOWN_BASE_CLASSES[Math.abs(errorCode)] || 'RPCError' + errorCode.toString().replace('-', 'Neg')
- }
- return snakeToCamelCase(
- errorCode
- .replace('FIRSTNAME', 'FIRST_NAME')
- .replace('SLOWMODE', 'SLOW_MODE')
- .toLowerCase(),
- 'Error',
- )
- }
- class TelegramError {
- constructor(codes, name, description) {
- // TODO Some errors have the same name but different integer codes
- // Should these be split into different files or doesn't really matter?
- // Telegram isn't exactly consistent with returned errors anyway.
- [this.intCode] = codes
- this.stringCode = name
- this.subclass = getClassName(codes[0])
- this.subclassExists = Math.abs(codes[0]) in KNOWN_BASE_CLASSES
- this.description = description
- this.hasCaptures = name.includes('_X')
- if (this.hasCaptures) {
- this.name = variableSnakeToCamelCase(getClassName(name.replace('_X', '')))
- this.pattern = variableSnakeToCamelCase(name.replace('_X', '_(\\d+)'))
- this.captureName = variableSnakeToCamelCase(description.match(/{(\w+)}/)[1])
- } else {
- this.name = variableSnakeToCamelCase(getClassName(name))
- this.pattern = variableSnakeToCamelCase(name)
- this.captureName = null
- }
- }
- }
- /**
- * Parses the input CSV file with columns (name, error codes, description)
- * and yields `Error` instances as a result.
- */
- const parseErrors = function* (csvFile) {
- const f = csvParse(fs.readFileSync(csvFile, { encoding: 'utf-8' })).slice(1)
- for (let line = 0; line < f.length; line++) {
- if (f[line].length !== 3) {
- throw new Error(`Columns count mismatch, unquoted comma in desc? (line ${line + 2})`)
- }
- let [name, codes, description] = f[line]
- codes =
- codes === '' ?
- [400] :
- codes.split(' ').map((x) => {
- if (isNaN(x)) {
- throw new Error(`Not all codes are integers (line ${line + 2})`)
- }
- return Number(x)
- })
- yield new TelegramError(codes, name, description)
- }
- }
- module.exports = {
- KNOWN_BASE_CLASSES,
- TelegramError,
- parseErrors,
- }
|