@@ -20,6 +20,7 @@ import {
2020 SET_RIGHT_FROM ,
2121 SET_RIGHT_UNTIL ,
2222} from "./actionTypes" ;
23+ import { isAbortError } from "../util/abort" ;
2324
2425export const setDateRange = ( from , until ) => ( {
2526 type : SET_DATE_RANGE ,
@@ -103,7 +104,15 @@ export const setQuery = (query) => ({
103104 payload : { query } ,
104105} ) ;
105106
107+ /**
108+ * ATTENTION! There may be race conditions:
109+ * Since a new controller is created every time a 'fetch' action is called
110+ * A badly timed 'abort' action may cancel the brand new 'fetch' action!
111+ */
106112let currentTimelineController ;
113+ let fetchTagController ;
114+ let fetchTagValuesController ;
115+
107116export function fetchTimeline ( url ) {
108117 return ( dispatch ) => {
109118 if ( currentTimelineController ) {
@@ -118,24 +127,62 @@ export function fetchTimeline(url) {
118127 . then ( ( data ) => {
119128 dispatch ( receiveTimeline ( data ) ) ;
120129 } )
130+ . catch ( ( e ) => {
131+ // AbortErrors are fine
132+ if ( ! isAbortError ( e ) ) {
133+ throw e ;
134+ }
135+ } )
121136 . finally ( ) ;
122137 } ;
123138}
124139
140+ export function abortTimelineRequest ( ) {
141+ return ( ) => {
142+ if ( currentTimelineController ) {
143+ currentTimelineController . abort ( ) ;
144+ }
145+ } ;
146+ }
147+
125148export function fetchTags ( query ) {
126149 return ( dispatch ) => {
150+ if ( fetchTagController ) {
151+ fetchTagController . abort ( ) ;
152+ }
153+ fetchTagController = new AbortController ( ) ;
154+
127155 dispatch ( requestTags ( ) ) ;
128156 return fetch ( `/labels?query=${ encodeURIComponent ( query ) } ` )
129157 . then ( ( response ) => response . json ( ) )
130158 . then ( ( data ) => {
131159 dispatch ( receiveTags ( data ) ) ;
132160 } )
161+ . catch ( ( e ) => {
162+ // AbortErrors are fine
163+ if ( ! isAbortError ( e ) ) {
164+ throw e ;
165+ }
166+ } )
133167 . finally ( ) ;
134168 } ;
135169}
136170
171+ export function abortFetchTags ( ) {
172+ return ( ) => {
173+ if ( fetchTagController ) {
174+ fetchTagController . abort ( ) ;
175+ }
176+ } ;
177+ }
178+
137179export function fetchTagValues ( query , tag ) {
138180 return ( dispatch ) => {
181+ if ( fetchTagValuesController ) {
182+ fetchTagValuesController . abort ( ) ;
183+ }
184+ fetchTagValuesController = new AbortController ( ) ;
185+
139186 dispatch ( requestTagValues ( tag ) ) ;
140187 return fetch (
141188 `/label-values?label=${ encodeURIComponent (
@@ -146,9 +193,22 @@ export function fetchTagValues(query, tag) {
146193 . then ( ( data ) => {
147194 dispatch ( receiveTagValues ( data , tag ) ) ;
148195 } )
196+ . catch ( ( e ) => {
197+ // AbortErrors are fine
198+ if ( ! fetchTagValuesController . signal . aborted ) {
199+ throw e ;
200+ }
201+ } )
149202 . finally ( ) ;
150203 } ;
151204}
205+ export function abortFetchTagValues ( ) {
206+ return ( ) => {
207+ if ( fetchTagValuesController ) {
208+ fetchTagValuesController . abort ( ) ;
209+ }
210+ } ;
211+ }
152212
153213let currentNamesController ;
154214export function fetchNames ( ) {
@@ -166,6 +226,19 @@ export function fetchNames() {
166226 . then ( ( data ) => {
167227 dispatch ( receiveNames ( data ) ) ;
168228 } )
229+ . catch ( ( e ) => {
230+ // AbortErrors are fine
231+ if ( ! isAbortError ( e ) ) {
232+ throw e ;
233+ }
234+ } )
169235 . finally ( ) ;
170236 } ;
171237}
238+ export function abortFetchNames ( ) {
239+ return ( ) => {
240+ if ( abortFetchNames ) {
241+ abortFetchNames . abort ( ) ;
242+ }
243+ } ;
244+ }
0 commit comments