fix: errors codegen

This commit is contained in:
alina 🌸 2023-10-12 05:24:16 +03:00
parent 0ca62ab375
commit 0841cbb031
Signed by: teidesu
SSH key fingerprint: SHA256:uNeCpw6aTSU4aIObXLvHfLkDa82HWH9EiOj9AXOIRpI
3 changed files with 44 additions and 15 deletions

View file

@ -4,26 +4,36 @@ import { snakeToCamel } from './utils'
const TEMPLATE_JS = ` const TEMPLATE_JS = `
const _descriptionsMap = JSON.parse('{descriptionsMap}') const _descriptionsMap = JSON.parse('{descriptionsMap}')
class RpcError extends Error { class RpcError extends Error {
constructor(code, text) { constructor(code, text, description) {
super(_descriptionsMap[text] || 'Unknown RPC error: [' + code + ':' + text + ']'); super(description || 'Unknown RPC error: [' + code + ':' + text + ']');
this.code = code; this.code = code;
this.text = text; this.text = text;
this.unknown = !_descriptionsMap[text];
} }
static is(err, text) { return err.constructor === RpcError && (!text || err.text === text); } static is(err, text) { return err.constructor === RpcError && (!text || err.text === text); }
is(text) { return this.text === text; } is(text) { return this.text === text; }
} }
RpcError.fromTl = function (obj) { RpcError.fromTl = function (obj) {
const err = new RpcError(obj.errorCode, obj.errorMessage); if (obj.errorMessage in _descriptionsMap) {
return new RpcError(obj.errorCode, obj.errorMessage, _descriptionsMap[obj.errorMessage]);
}
if (err in _descriptionsMap) return err; var err = new RpcError(obj.errorCode, obj.errorMessage);
var match;
let match;
{matchers} {matchers}
else return err
err.message = _descriptionsMap[err.text];
return err return err
} }
RpcError.create = function(code, text) {
var desc = _descriptionsMap[text];
var err = new RpcError(code, text, desc);
if (!desc) {
err.unknown = true;
}
return err;
}
{statics} {statics}
{exports}RpcError = RpcError; {exports}RpcError = RpcError;
`.trimStart() `.trimStart()
@ -115,6 +125,8 @@ export function generateCodeForErrors(errors: TlErrors, exports = 'exports.'): [
staticsTs += ` static ${name}: ${code};\n` staticsTs += ` static ${name}: ${code};\n`
} }
let first = true
for (const error of Object.values(errors.errors)) { for (const error of Object.values(errors.errors)) {
const [name, placeholders] = parseCode(error.name, error._paramNames) const [name, placeholders] = parseCode(error.name, error._paramNames)
@ -131,7 +143,10 @@ export function generateCodeForErrors(errors: TlErrors, exports = 'exports.'): [
const regex = name.replace('%d', '(\\d+)') const regex = name.replace('%d', '(\\d+)')
const setters = placeholders.map((it, i) => `err.${it} = parseInt(match[${i + 1}])`).join('; ') const setters = placeholders.map((it, i) => `err.${it} = parseInt(match[${i + 1}])`).join('; ')
matchers += ` if ((match=obj.errorMessage.match(/^${regex}$/))!=null){ err.text = '${name}'; ${setters} }\n` matchers += ` ${
first ? '' : 'else '
}if ((match=err.text.match(/^${regex}$/))!=null){ err.text = '${name}'; ${setters} }\n`
first = false
} }
} }

View file

@ -234,16 +234,9 @@ export function generateTypescriptDefinitionsForTlSchema(
let js = PRELUDE_JS.replace('$NS$', namespace).replace('$LAYER$', String(layer)) let js = PRELUDE_JS.replace('$NS$', namespace).replace('$LAYER$', String(layer))
if (errors) { if (errors) {
// ts += '\n namespace errors {\n'
// js += 'ns.errors = {};\n(function(ns){\n'
const [_ts, _js] = generateCodeForErrors(errors, 'ns.') const [_ts, _js] = generateCodeForErrors(errors, 'ns.')
// ts += indent(8, _ts)
ts += _ts ts += _ts
js += _js js += _js
// ts += '}\n'
// js += '})(ns.errors);\n'
} }
const namespaces = groupTlEntriesByNamespace(schema.entries) const namespaces = groupTlEntriesByNamespace(schema.entries)

View file

@ -59,8 +59,29 @@ async function generateWriters(apiSchema: TlFullSchema, mtpSchema: TlFullSchema)
await writeFile(OUT_WRITERS_FILE, ESM_PRELUDE + code) await writeFile(OUT_WRITERS_FILE, ESM_PRELUDE + code)
} }
// put common errors to the top so they are parsed first
const ERRORS_ORDER = ['FLOOD_WAIT_%d', 'FILE_MIGRATE_%d', 'NETWORK_MIGRATE_%d', 'PHONE_MIGRATE_%d', 'STATS_MIGRATE_%d']
function putCommonErrorsFirst(errors: TlErrors) {
const newErrors: TlErrors['errors'] = {}
for (const name of ERRORS_ORDER) {
if (name in errors.errors) {
newErrors[name] = errors.errors[name]
}
}
for (const name in errors.errors) {
if (name in newErrors) continue
newErrors[name] = errors.errors[name]
}
errors.errors = newErrors
}
async function main() { async function main() {
const errors = JSON.parse(await readFile(ERRORS_JSON_FILE, 'utf8')) as TlErrors const errors = JSON.parse(await readFile(ERRORS_JSON_FILE, 'utf8')) as TlErrors
putCommonErrorsFirst(errors)
const [apiSchema, apiLayer] = unpackTlSchema( const [apiSchema, apiLayer] = unpackTlSchema(
JSON.parse(await readFile(API_SCHEMA_JSON_FILE, 'utf8')) as TlPackedSchema, JSON.parse(await readFile(API_SCHEMA_JSON_FILE, 'utf8')) as TlPackedSchema,