mirror of
https://github.com/simonbrunel/qtpromise.git
synced 2024-11-24 03:30:57 +08:00
Allow undefined rejection reason
While not recommended because it makes tracking errors more difficult, it's now possible to reject a promise without explicit reason, in which case, a built-in `QPromiseUndefinedException` is thrown. This is done in anticipation of handling rejection signals without argument.
This commit is contained in:
parent
16229fc2c9
commit
fa5a4192ff
@ -35,3 +35,35 @@ QPromise<int> promise([](const auto& resolve, const auto& reject) {
|
||||
// {...}
|
||||
});
|
||||
```
|
||||
|
||||
**Undefined rejection reason**
|
||||
|
||||
*Since: 0.5.0*
|
||||
|
||||
While not recommended because it makes tracking errors more difficult, it's also
|
||||
possible to reject a promise without explicit reason, in which case, a built-in
|
||||
`QPromiseUndefinedException` is thrown:
|
||||
|
||||
```cpp
|
||||
QPromise<int> promise([](const QPromiseResolve<int>& resolve, const QPromiseReject<int>& reject) {
|
||||
async_method([=](bool success, int result) {
|
||||
if (success) {
|
||||
resolve(result);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
```cpp
|
||||
// The exception can be caught explicitly
|
||||
promise.fail([](const QPromiseUndefinedException&) {
|
||||
// { ... }
|
||||
})
|
||||
|
||||
// ... or implicitly (since undefined)
|
||||
promise.fail([]() {
|
||||
// { ... }
|
||||
})
|
||||
```
|
||||
|
@ -20,6 +20,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class QPromiseUndefinedException : public QException
|
||||
{
|
||||
public:
|
||||
void raise() const Q_DECL_OVERRIDE { throw *this; }
|
||||
QPromiseUndefinedException* clone() const Q_DECL_OVERRIDE
|
||||
{
|
||||
return new QPromiseUndefinedException(*this);
|
||||
}
|
||||
};
|
||||
|
||||
// QPromiseError is provided for backward compatibility and will be
|
||||
// removed in the next major version: it wasn't intended to be used
|
||||
// directly and thus should not be part of the public API.
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef QTPROMISE_QPROMISERESOLVER_H
|
||||
#define QTPROMISE_QPROMISERESOLVER_H
|
||||
|
||||
#include "qpromiseerror.h"
|
||||
|
||||
// Qt
|
||||
#include <QExplicitlySharedDataPointer>
|
||||
|
||||
@ -34,6 +36,17 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void reject()
|
||||
{
|
||||
auto promise = m_d->promise;
|
||||
if (promise) {
|
||||
Q_ASSERT(promise->isPending());
|
||||
promise->m_d->reject(QtPromise::QPromiseUndefinedException());
|
||||
promise->m_d->dispatch();
|
||||
release();
|
||||
}
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
void resolve(V&& value)
|
||||
{
|
||||
@ -115,6 +128,11 @@ public:
|
||||
m_resolver.reject(std::forward<E>(error));
|
||||
}
|
||||
|
||||
void operator()() const
|
||||
{
|
||||
m_resolver.reject();
|
||||
}
|
||||
|
||||
private:
|
||||
mutable QtPromisePrivate::PromiseResolver<T> m_resolver;
|
||||
};
|
||||
|
@ -33,6 +33,8 @@ private Q_SLOTS:
|
||||
void rejectSync_void();
|
||||
void rejectAsync();
|
||||
void rejectAsync_void();
|
||||
void rejectUndefined();
|
||||
void rejectUndefined_void();
|
||||
void connectAndResolve();
|
||||
void connectAndReject();
|
||||
};
|
||||
@ -234,6 +236,30 @@ void tst_qpromise_construct::rejectThrowTwoArgs_void()
|
||||
QCOMPARE(waitForError(p, QString()), QString("foo"));
|
||||
}
|
||||
|
||||
void tst_qpromise_construct::rejectUndefined()
|
||||
{
|
||||
QPromise<int> p([](const QPromiseResolve<int>&, const QPromiseReject<int>& reject) {
|
||||
QtPromisePrivate::qtpromise_defer([=]() {
|
||||
reject();
|
||||
});
|
||||
});
|
||||
|
||||
QCOMPARE(p.isPending(), true);
|
||||
QCOMPARE(waitForRejected<QPromiseUndefinedException>(p), true);
|
||||
}
|
||||
|
||||
void tst_qpromise_construct::rejectUndefined_void()
|
||||
{
|
||||
QPromise<void> p([](const QPromiseResolve<void>&, const QPromiseReject<void>& reject) {
|
||||
QtPromisePrivate::qtpromise_defer([=]() {
|
||||
reject();
|
||||
});
|
||||
});
|
||||
|
||||
QCOMPARE(p.isPending(), true);
|
||||
QCOMPARE(waitForRejected<QPromiseUndefinedException>(p), true);
|
||||
}
|
||||
|
||||
// https://github.com/simonbrunel/qtpromise/issues/6
|
||||
void tst_qpromise_construct::connectAndResolve()
|
||||
{
|
||||
|
@ -44,4 +44,14 @@ static inline E waitForError(const QtPromise::QPromise<void>& promise, const E&
|
||||
return error;
|
||||
}
|
||||
|
||||
template <typename E, typename T>
|
||||
static inline bool waitForRejected(const T& promise)
|
||||
{
|
||||
bool result = false;
|
||||
promise.tapFail([&](const E&) {
|
||||
result = true;
|
||||
}).wait();
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif // QTPROMISE_TESTS_AUTO_SHARED_UTILS_H
|
||||
|
Loading…
Reference in New Issue
Block a user