Vk-io: [bug] vk.api envia parâmetros iguais a indefinidos

Criado em 27 ago. 2020  ·  18Comentários  ·  Fonte: negezor/vk-io

Ei!
Em resumo, chamar qualquer API com um parâmetro que especifique explicitamente o valor undefined leva ao fato de que ele é transferido para o VK. Abaixo está um exemplo.

O que você fez?

await ctx.send("it'll fail", {
    keyboard: undefined
});

ctx - contexto do evento message_new

Снимок экрана 2020-08-28 в 00 53 43

O que você esperava que acontecesse?

Parâmetros com o valor undefined não devem ser passados, exatamente como se fossem omitidos.

Qual foi o resultado real?

O VK-IO traduz undefined em uma string e a entrega ao servidor.

Versões

| pacote | versão |
| ---------------------------------- | ------- |
| vk-io | 4.0.1 |
| node | 12.17.0 |
| TypeScript | 4.0.2 |
| yarn | 1.22.4 |

vk-io

Todos 18 comentários

Não, espere, não funciona assim um pouco. Explicar para você?

Vamos lá, o que está um pouco errado?

Que os parâmetros sejam enviados usando URLSearchParams

const params = {
   message: 'hello',
   keyboard: undefined
};

console.log(new URLSearchParams(params));
// Выведет: URLSearchParams { 'message' => 'hello', 'keyboard' => 'undefined' }

@isinkin Sim, mas já escrevi no PR que isso é um bug, pois o TypeScript não faz diferença alguma, o parâmetro não é especificado ou é especificado com o valor undefined , mas em tempo de execução isso já leva a um erro de API. Esta é uma armadilha direta de algum tipo.

@zardoy por que isso é um bug?

const obj = {
  key: undefined,
}

const properties = Object.getOwnPropertyNames(obj)

console.log(properties)

A propriedade é declarada, seu tipo é indefinido, e quando convertida em string, obtém-se a string 'undefined'.
O fato de algo não funcionar bem para o ts já se aplica ao ts, o runtime é na v8, via de regra, e ele só suporta javascript.

const obj = {
  key: undefined,
}

const properties = Object.getOwnPropertyNames(obj)

console.log(properties)

Isso mesmo, mas por que essa transformação? Afinal, se queremos passar explicitamente uma string com tal conteúdo, por que não passar explicitamente a string como parâmetro?

vk.api.messages.send({
    message: "undefined" // - так ок
});

Talvez você esteja certo de que isso não é um bug, mas apenas uma armadilha devido ao fato de que ts não lança um erro de compilação quando você especifica explicitamente undefined . Porém, minha sugestão no PR é que o comportamento quando omitimos o parâmetro completamente e especificamos undefined seria o mesmo, pois nem sempre

Sori, que fechei, agora vou acrescentar.

@zardoy eu entendo o que você quer dizer.

Certamente você escreve algo como

let someVariable;

const query = {
  key: someVariable,
}

send(query)

Acho que esse problema está do lado do usuário, você precisa escrever de uma forma diferente, e com esse pr você quebra a compatibilidade com versões anteriores.

Acho que esse problema está do lado do usuário, você precisa escrever de uma forma diferente, e com esse pr você quebra a compatibilidade com versões anteriores.

Eu concordo.

Basta olhar onde o cachorro está enterrado (um exemplo mais ilustrativo):

  • Eu não poderia soletrar assim
    Снимок экрана 2020-08-28 в 13 39 24

  • Eu já posso fazer isso
    Снимок экрана 2020-08-28 в 13 39 59

ts vai jurar bem, embora o pedido de fato seja o mesmo. Apenas uma armadilha para o usuário

@zardoy então não escreva nada se você não quiser passar esse parâmetro, ele funcionará do jeito que você quiser

vk.api.messages.send()

Há sim uma incompatibilidade de comportamento, com JSON.stringify() undefined será perdido. Enquanto URLSearchParams leva tudo para uma string. Isso não quebrará a compatibilidade com versões anteriores, pois é undefined que é verificado, não "undefined" .

Mas agora vamos perder mensagens interessantes no chat na forma de undefined :)

@negezor sobre essas mensagens que eu quis dizer, é possível que alguém use o tipo indefinido quando quiser imprimir esse texto)

upd: bem, em vez de undefined, uma exceção será lançada em alguns casos, por exemplo, quando a mensagem estiver vazia.

Por que você está especificando undefined nos parâmetros?

A indicação explícita é um exemplo simplificado apenas para fins de compreensão. Na realidade, esse valor pode vir de uma função, quando os objetos são mesclados e de muito mais. Aqui está um exemplo do PR:

await ctx.send("Hey` there!", {
    keyboard: await getKeyboardToSend() //undefined | KeyboardBuilder - соответствие типов, но ошибка ругается API
});

Aqui eu uso como um tipo de fallback, o que significaria que você não precisa mostrar o teclado

O fato de URLSearchParams coletar undefined é provavelmente mais flexível e correto, mas menos conveniente.

Eu não sei muito sobre vkapi e os recursos desta lib e não posso dizer se há um problema, mas se realmente houver um problema de comportamentos diferentes em uma biblioteca, isso deve ser resolvido.

Eu acho que você pode passar o corpo da solicitação diretamente e ele é convertido em JSON usando JSON.stringify, que trunca indefinido ao contrário de URLSearchParams, isso é confuso para os usuários.

O fato de URLSearchParams coletar undefined é provavelmente mais flexível e correto, mas menos conveniente.

@talentumtuum não concorda muito, posso até dar um exemplo de outra lib bem grande.
Existe essa biblioteca prisma (através dela você pode fazer consultas ao banco de dados). E aqui está um de seus exemplos:

const hisNotes = await prisma.userNote.findMany({
    where: {
        userName: "Dmitriy" // вернет записки только дмитрия
    }
});
const allNotes = await prisma.userNote.findMany({
    where: {
        userName: undefined // не вернет записки пользователя "undefined"
    }
});
// это равносильно
allNotes = await prisma.userNote.findMany({ });

upd: bem, em vez de undefined, uma exceção será lançada em alguns casos, por exemplo, quando a mensagem estiver vazia.

Concordo, imagine se um bot spam "indefinido" em qualquer comando. Melhor exceção do que bobagem silenciosa xd

upd: talvez eles vejam pelo menos nos logs, mas eles vão corrigi-lo

Ainda assim, acho que um bug é melhor do que um post problemático. Em ferramentas como o Sentry, é difícil rastrear o que não é um bug. A versão principal 4 visava uma melhor interação com a biblioteca e o undefined explícito não

Isso também corrige o comportamento não óbvio entre URLSearamParams e JSON.stringify() , corrigido em https://github.com/negezor/vk-io/commit/1026d333a07ff50423100f331e74a8041e2f567d , postado em 4.0.2

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

alexey2baranov picture alexey2baranov  ·  8Comentários

ogmishanya picture ogmishanya  ·  4Comentários

SOS
helix-team picture helix-team  ·  4Comentários

T1MOXA picture T1MOXA  ·  22Comentários

ProgrammingLife picture ProgrammingLife  ·  9Comentários