Worum könnte es hier gehen? [TsLint-Fehler: "Versprechen müssen angemessen behandelt werden"]

76

Ich mache einige grundlegende asynchrone Operationen mit async/awaitTypeScript, aber TSLint gibt unten mysteriöse Fehlermeldungen für diese beiden Funktionen aus. Hat jemand diese Fehler schon einmal erlebt? In der Fehlerausgabe wird die maßgebliche Regel nicht erwähnt, daher verstehe ich nicht, was diese verursacht. Irgendwelche Ideen wären sehr dankbar.

Die Hauptanfrage:

import * as rp from 'request-promise'

export function getRequest(address: rp.Options): rp.RequestPromise {
  return rp(address)
}

Exportierte asynchrone Funktion:

export async function getStatus(message: Message) {
  try {
    const res = await getRequest(address)
    if (res.ready) {
      message.reply('...')
    } else {
      message.reply('...')
    }
  } catch (err) {
    message.reply(err)
  }
}

Dies wird: Promises must be handled appropriatelyund await of non-Promisefür Zeile 3.

Die einfache Funktion, die diesen Export verwendet, ist:

client.on('message', message => {
  if (message.content === 'green') {
    getStatus(message)
  }
})

Das bekommt auch Promises must be handled appropriately.

Zusätzliche Information:

Obwohl die Fehlermeldung dies nicht erwähnt, scheint dies die maßgebliche Regel zu sein für Promises must be handled appropriately: https://palantir.github.io/tslint/rules/no-floating-promises/

In dieser Ausgabe wird Folgendes erwähnt await of non-Promise: https://github.com/palantir/tslint/issues/2661

cinnaroll45
quelle
3
Können Sie auch die Funktion getRequest in der Frage posten, danke.
Rikusor
Toller Punkt, ich habe es hinzugefügt.
Cinnaroll45
Ich rate hier nur, aber dies könnte sein, dass tslint nicht erkennt, dass die rp-Funktion ein Versprechen zurückgibt. Sie könnten versuchen, einen Typ dafür festzulegen, Exportfunktion getRequest (Adresse: rp.Options): Promise <any> {... Lassen Sie mich wissen, ob dies funktioniert, damit ich nicht mehr Zeit damit verbringe, dies zu überprüfen :)
Rikusor
Zurückgeben eines Versprechens <any> Fehler in der IDE, die nicht mit dem kompatibel sind, was tatsächlich zurückgegeben wird rp. Also habe ich folgendes verwendet: export function getRequest(address: rp.Options): rp.RequestPromise { return rp(address) }Dies erfüllt die IDE, aber ich erhalte immer noch genau die gleichen Fehler im ersten Beitrag.
Cinnaroll45

Antworten:

110

Das ist eine beschissene Fehlermeldung. Ein besserer könnte sein,

Jeder Ausdruck vom Typ Promisemuss mit einem Aufruf .catchoder einem Aufruf .thenmit einem Ablehnungshandler ( Quelle ) enden .

Also zum Beispiel, wenn Sie es tun

PromiseFunction()
  .catch(err => handle(err))
  .then(() => console.log('this will succeed'))

dann wirst du immer noch ein tslint-Problem haben, weil die Art von .then(...)ein Versprechen ist und es mit einem Haken enden muss. Das Update würde beispielsweise eine .catchKlausel anhängen

PromiseFunction()
  .catch(err => handle(err))
  .then(() => console.log('this will succeed'))
  .catch(() => 'obligatory catch')

oder deaktivieren Sie einfach tslint für diese Leitung über:

PromiseFunction()
  .catch(err => handle(err))
  // tslint:disable-next-line:no-unsafe-any
  .then(() => console.log('this will succeed'))

Alternativ können Sie die Reihenfolge der Anweisungen .thenund umkehren .catch. Dies verhindert jedoch die .thenAusführung von, wenn ein Fehler auftritt, den Sie vermutlich möchten, wenn Sie auf dieses Problem gestoßen sind.

Kriegsähnlicher Schimpanse
quelle
26
Hallo Elliot, ich habe die no-floating-promisesRegel geschrieben und bin damit einverstanden, dass die Fehlermeldung nicht großartig ist. Wenn Sie eine PR mit einer besseren Beschreibung senden möchten, bin ich alles dafür!
Josh
57

Manchmal möchten Sie vielleicht das Versprechen anrufen, müssen aber mit der Antwort nichts anfangen. Eine Routenänderung oder etwas anderes.

also statt:

promiseFunction().then().catch()
try/catch async/await

du kannst tun:

void promiseFunction();
T04435
quelle
5
Schön, dass dies funktioniert. Es wäre praktisch, einen Verweis auf die voidSyntax zu sehen
Damian Green,
Das funktioniert großartig, aber für mein Leben kann ich in keiner Dokumentation irgendwo einen Hinweis darauf finden.
Ach
1
Anscheinend ist dies der JavaScript-Operator "void" .
Ach
Das Setzen einer Leere vor die aufgerufene Funktion hat funktioniert.
Sarthak Srivastav
Benutze das nicht. Du hast es nur verschleiert. Es ist immer noch ein schwebendes Versprechen. Und es ist eine ungewöhnliche Verwendung davon.
Dominik
6

Ich habe die gleiche Ausnahme bekam , wenn ich erstellt haben firebase-functionmitfirebase-tool

const ref = admin.database().ref("path/to/database/object");

ref.once("value").catch(error =>{  // line 22
    response.send( error() );
}).then( snapshot =>{
    response.send( snapshot.val );
})

Dieser Code wird nicht kompiliert und return

ERROR: /src/index.ts[22, 5]: Promises must be handled appropriately

Ich habe die Orte von catchund geändert then.

ref.once(...).then(...).catch(...)

Dieser Code ist Arbeit, es tut mir leid, aber ich habe keine Erklärung

So viel Erstaunliches, wenn App einen Fehler ohne catchBlock zurückgibt, auch wenn firebase docnicht erwähnt, dass dies catcherforderlich ist.

Vahe Gharibyan
quelle
4

Ihre getStatusFunktion ist so definiert, dass sie ein Versprechen zurückgibt:

// All functions marked as async returns a promise:
async function getStatus(message: Message) {/* ... */}

Aber Sie haben angerufen, getStatusohne anzurufen, dann:

getStatus(message)

Daher glaubt der Compiler, Sie hätten vergessen, Ihren asynchronen Code zu verarbeiten. Alles was Sie tun müssen, ist anzurufen .then():

getStatus(message).then(() => console.log('done'));
Slebetman
quelle
Du hast recht, aber diese Linie wird getStatus(message).then(() => console.log('done'))immer noch Promises must be handled appropriately.
Cinnaroll45
@ cinnaroll45 Hast du auch versucht, damit umzugehen .catch()? getStatus().then().catch()
Slebetman
Ja, versucht bot .catch()und ein try/catchfür den Aufruf getStatus()immer noch den gleichen Fehler wie mein erster Kommentar.
Cinnaroll45
1
@ cinnaroll45 Konnten Sie dieses Problem lösen? Ich habe auch das gleiche Problem und kann es nicht lösen
Prafful Garg
1
Ich habe abgestimmt, weil dies einfach falsch ist. Tslint sucht nach einem Fang oder dann mit Ablehnungshandler.
Warlike Schimpanse
1

Ich denke, dieses Problem kann durch Warten auf die Funktion getStatus behoben werden , da es sich um eine asynchrone Funktion handelt. Die Nachricht sagt es deutlich, aber die Zeilennummer sorgt für Verwirrung. Um ehrlich zu sein, habe ich auch einige Zeit gebraucht.

Sie können diesen Flusenfehler durch diese Codeänderung beheben:

client.on('message', message => {
 if (message.content === 'green') {
   await getStatus(message)
}});

Meiner Meinung nach ist es keine gute Idee, diese spezifischen Fehler auszuschalten. Sie sind nützlich, weil Sie den Code auf andere Weise nicht asynchron ausführen würden.

Crix
quelle
1
Dies ändert das Verhalten des Codes. Vor der Zugabe await, getStatuswürde den Faden nicht halten. Der Autor möchte die spätere Ausführung möglicherweise nicht verzögern. Dies könnte eine App unnötig aufhalten.
Jmealy
1

Wenn Sie eine nichtige asynchrone Funktion mit Typoskript-Eslint schreiben, erhalten Sie eine Beschwerde, wenn Sie asynchrone Funktionen ohne Wartezeit schreiben. Dies ist besonders für die letzte Zeile der Funktion leicht zu vergessen.

const sendSyncPlayCommandToWatchers = async (): Promise<void> => {
  ...
  someAsyncFunction()
}

Sie erhalten

Fehler Versprechen müssen angemessen behandelt werden @ typescript-eslint / no-float-Versprechen

Sie müssen das Schlüsselwort await in die letzte Zeile einfügen (oder sicherstellen, dass Sie das Versprechen mit try / catch behandeln, wie in den vorherigen Antworten erwähnt

const sendSyncPlayCommandToWatchers = async () => {
  ...
  await someAsyncFunction()
}

Ich denke, dies wird auch dazu beitragen, beim Debuggen einen besseren Stack-Trace zu erhalten.

Cyril Duchon-Doris
quelle