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
|
// QPromiseError is provided for backward compatibility and will be
|
||||||
// removed in the next major version: it wasn't intended to be used
|
// removed in the next major version: it wasn't intended to be used
|
||||||
// directly and thus should not be part of the public API.
|
// directly and thus should not be part of the public API.
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#ifndef QTPROMISE_QPROMISERESOLVER_H
|
#ifndef QTPROMISE_QPROMISERESOLVER_H
|
||||||
#define QTPROMISE_QPROMISERESOLVER_H
|
#define QTPROMISE_QPROMISERESOLVER_H
|
||||||
|
|
||||||
|
#include "qpromiseerror.h"
|
||||||
|
|
||||||
// Qt
|
// Qt
|
||||||
#include <QExplicitlySharedDataPointer>
|
#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>
|
template <typename V>
|
||||||
void resolve(V&& value)
|
void resolve(V&& value)
|
||||||
{
|
{
|
||||||
@ -115,6 +128,11 @@ public:
|
|||||||
m_resolver.reject(std::forward<E>(error));
|
m_resolver.reject(std::forward<E>(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void operator()() const
|
||||||
|
{
|
||||||
|
m_resolver.reject();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable QtPromisePrivate::PromiseResolver<T> m_resolver;
|
mutable QtPromisePrivate::PromiseResolver<T> m_resolver;
|
||||||
};
|
};
|
||||||
|
@ -33,6 +33,8 @@ private Q_SLOTS:
|
|||||||
void rejectSync_void();
|
void rejectSync_void();
|
||||||
void rejectAsync();
|
void rejectAsync();
|
||||||
void rejectAsync_void();
|
void rejectAsync_void();
|
||||||
|
void rejectUndefined();
|
||||||
|
void rejectUndefined_void();
|
||||||
void connectAndResolve();
|
void connectAndResolve();
|
||||||
void connectAndReject();
|
void connectAndReject();
|
||||||
};
|
};
|
||||||
@ -234,6 +236,30 @@ void tst_qpromise_construct::rejectThrowTwoArgs_void()
|
|||||||
QCOMPARE(waitForError(p, QString()), QString("foo"));
|
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
|
// https://github.com/simonbrunel/qtpromise/issues/6
|
||||||
void tst_qpromise_construct::connectAndResolve()
|
void tst_qpromise_construct::connectAndResolve()
|
||||||
{
|
{
|
||||||
|
@ -44,4 +44,14 @@ static inline E waitForError(const QtPromise::QPromise<void>& promise, const E&
|
|||||||
return error;
|
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
|
#endif // QTPROMISE_TESTS_AUTO_SHARED_UTILS_H
|
||||||
|
Loading…
Reference in New Issue
Block a user