@@ -719,6 +719,30 @@ void main() {
719
719
connection.prepare (httpStatus: 200 , body: 'nonsense' );
720
720
}
721
721
722
+ void prepareRateLimitExceptionCode () {
723
+ // Example from the Zulip API docs:
724
+ // https://zulip.com/api/rest-error-handling#rate-limit-exceeded
725
+ // (The actual HTTP status should be 429, but that seems undocumented.)
726
+ connection.prepare (httpStatus: 400 , json: {
727
+ 'result' : 'error' , 'code' : 'RATE_LIMIT_HIT' ,
728
+ 'msg' : 'API usage exceeded rate limit' ,
729
+ 'retry-after' : 28.706807374954224 });
730
+ }
731
+
732
+ void prepareRateLimitExceptionStatus () {
733
+ // The HTTP status code for hitting a rate limit,
734
+ // but for some reason a boring BAD_REQUEST error body.
735
+ connection.prepare (httpStatus: 429 , json: {
736
+ 'result' : 'error' , 'code' : 'BAD_REQUEST' , 'msg' : 'Bad request' });
737
+ }
738
+
739
+ void prepareRateLimitExceptionMalformed () {
740
+ // The HTTP status code for hitting a rate limit,
741
+ // but for some reason a non-JSON body.
742
+ connection.prepare (httpStatus: 429 ,
743
+ body: '<html><body>An error occurred.</body></html>' );
744
+ }
745
+
722
746
void prepareZulipApiExceptionBadRequest () {
723
747
connection.prepare (httpStatus: 400 , json: {
724
748
'result' : 'error' , 'code' : 'BAD_REQUEST' , 'msg' : 'Bad request' });
@@ -749,6 +773,18 @@ void main() {
749
773
checkRetry (prepareMalformedServerResponseException);
750
774
});
751
775
776
+ test ('retries on rate limit: code RATE_LIMIT_HIT' , () {
777
+ checkRetry (prepareRateLimitExceptionCode);
778
+ });
779
+
780
+ test ('retries on rate limit: status 429 ZulipApiException' , () {
781
+ checkRetry (prepareRateLimitExceptionStatus);
782
+ });
783
+
784
+ test ('retries on rate limit: status 429 MalformedServerResponseException' , () {
785
+ checkRetry (prepareRateLimitExceptionMalformed);
786
+ });
787
+
752
788
test ('retries on generic ZulipApiException' , () {
753
789
checkRetry (prepareZulipApiExceptionBadRequest);
754
790
});
@@ -882,6 +918,24 @@ void main() {
882
918
"Error connecting to Zulip at" );
883
919
});
884
920
921
+ test ('report rate limit: code RATE_LIMIT_HIT' , () {
922
+ checkReported (prepareRateLimitExceptionCode).startsWith (
923
+ "Error connecting to Zulip. Retrying…\n "
924
+ "Error connecting to Zulip at" );
925
+ });
926
+
927
+ test ('report rate limit: status 429 ZulipApiException' , () {
928
+ checkReported (prepareRateLimitExceptionStatus).startsWith (
929
+ "Error connecting to Zulip. Retrying…\n "
930
+ "Error connecting to Zulip at" );
931
+ });
932
+
933
+ test ('report rate limit: status 429 MalformedServerResponseException' , () {
934
+ checkReported (prepareRateLimitExceptionMalformed).startsWith (
935
+ "Error connecting to Zulip. Retrying…\n "
936
+ "Error connecting to Zulip at" );
937
+ });
938
+
885
939
test ('report generic ZulipApiException' , () {
886
940
checkReported (prepareZulipApiExceptionBadRequest).startsWith (
887
941
"Error connecting to Zulip. Retrying…\n "
0 commit comments