fix: ignore 404 while collecting jira issue worklog
diff --git a/plugins/helper/api_async_client.go b/plugins/helper/api_async_client.go
index 20d4f89..b18be35 100644
--- a/plugins/helper/api_async_client.go
+++ b/plugins/helper/api_async_client.go
@@ -139,7 +139,11 @@
 				res.Body = io.NopCloser(bytes.NewBuffer(body))
 			}
 		}
-
+		if err == ErrIgnoreAndContinue {
+			// make sure defer func got be executed
+			err = nil
+			return nil
+		}
 		// check
 		needRetry := false
 		if err != nil {
@@ -198,6 +202,7 @@
 	GetQps() float64
 	Add(delta int)
 	Done()
+	SetAfterFunction(callback ApiClientAfterResponse)
 }
 
 var _ RateLimitedApiClient = (*ApiAsyncClient)(nil)
diff --git a/plugins/helper/api_client.go b/plugins/helper/api_client.go
index 33b7ef7..4b941af 100644
--- a/plugins/helper/api_client.go
+++ b/plugins/helper/api_client.go
@@ -21,6 +21,7 @@
 	"bytes"
 	"context"
 	"encoding/json"
+	"errors"
 	"fmt"
 	"io"
 	"io/ioutil"
@@ -38,6 +39,8 @@
 type ApiClientBeforeRequest func(req *http.Request) error
 type ApiClientAfterResponse func(res *http.Response) error
 
+var ErrIgnoreAndContinue = errors.New("ignore and continue")
+
 // ApiClient is designed for simple api requests
 type ApiClient struct {
 	client        *http.Client
@@ -220,6 +223,9 @@
 	// after recieve
 	if apiClient.afterReponse != nil {
 		err = apiClient.afterReponse(res)
+		if err == ErrIgnoreAndContinue {
+			return res, err
+		}
 		if err != nil {
 			res.Body.Close()
 			return nil, err
diff --git a/plugins/helper/api_collector.go b/plugins/helper/api_collector.go
index 23cbb09..ad057e6 100644
--- a/plugins/helper/api_collector.go
+++ b/plugins/helper/api_collector.go
@@ -81,6 +81,7 @@
 	GetTotalPages  func(res *http.Response, args *ApiCollectorArgs) (int, error)
 	Concurrency    int
 	ResponseParser func(res *http.Response) ([]json.RawMessage, error)
+	AfterResponse  ApiClientAfterResponse
 }
 
 type ApiCollector struct {
@@ -118,11 +119,22 @@
 	if args.Concurrency < 1 {
 		args.Concurrency = 1
 	}
-	return &ApiCollector{
+	apicllector := &ApiCollector{
 		RawDataSubTask: rawDataSubTask,
 		args:           &args,
 		urlTemplate:    tpl,
-	}, nil
+	}
+	if args.AfterResponse != nil {
+		apicllector.SetAfterResponse(args.AfterResponse)
+	} else {
+		apicllector.SetAfterResponse(func(res *http.Response) error {
+			if res.StatusCode == http.StatusUnauthorized {
+				return fmt.Errorf("authentication failed, please check your AccessToken")
+			}
+			return nil
+		})
+	}
+	return apicllector, nil
 }
 
 // Start collection
@@ -284,6 +296,10 @@
 	return buf.String(), nil
 }
 
+func (collector *ApiCollector) SetAfterResponse(f ApiClientAfterResponse) {
+	collector.args.ApiClient.SetAfterFunction(f)
+}
+
 // stepFetch collect pages synchronously. In practice, several stepFetch running concurrently, we could stop all of them by calling `cancel`.
 func (collector *ApiCollector) stepFetch(ctx context.Context, cancel func(), reqData RequestData) error {
 	// channel `c` is used to make sure fetchAsync is called serially
diff --git a/plugins/jira/tasks/api_client.go b/plugins/jira/tasks/api_client.go
index 4896c05..7432ca0 100644
--- a/plugins/jira/tasks/api_client.go
+++ b/plugins/jira/tasks/api_client.go
@@ -86,3 +86,13 @@
 	}
 	return serverInfo, res.StatusCode, nil
 }
+
+func ignoreHTTPStatus404(res *http.Response) error {
+	if res.StatusCode == http.StatusUnauthorized {
+		return fmt.Errorf("authentication failed, please check your AccessToken")
+	}
+	if res.StatusCode == http.StatusNotFound {
+		return helper.ErrIgnoreAndContinue
+	}
+	return nil
+}
diff --git a/plugins/jira/tasks/changelog_collector.go b/plugins/jira/tasks/changelog_collector.go
index bd3f37b..2f13774 100644
--- a/plugins/jira/tasks/changelog_collector.go
+++ b/plugins/jira/tasks/changelog_collector.go
@@ -98,6 +98,7 @@
 			}
 			return data.Values, nil
 		},
+		AfterResponse: ignoreHTTPStatus404,
 	})
 
 	if err != nil {
diff --git a/plugins/jira/tasks/remotelink_collector.go b/plugins/jira/tasks/remotelink_collector.go
index a38d8ba..102805d 100644
--- a/plugins/jira/tasks/remotelink_collector.go
+++ b/plugins/jira/tasks/remotelink_collector.go
@@ -96,6 +96,7 @@
 			}
 			return result, nil
 		},
+		AfterResponse: ignoreHTTPStatus404,
 	})
 	if err != nil {
 		return err
diff --git a/plugins/jira/tasks/worklog_collector.go b/plugins/jira/tasks/worklog_collector.go
index 70e873d..e0ad9da 100644
--- a/plugins/jira/tasks/worklog_collector.go
+++ b/plugins/jira/tasks/worklog_collector.go
@@ -79,6 +79,7 @@
 			}
 			return data.Worklogs, nil
 		},
+		AfterResponse: ignoreHTTPStatus404,
 	})
 	if err != nil {
 		logger.Error("collect board error:", err)