A Golang job scheduling library that lets you run Go functions at pre-determined intervals using cron expressions, fixed durations, daily, weekly, monthly, or one-time schedules with support for distributed deployments.
All gocron errors are defined as package-level var values and can be matched with errors.Is.
import "github.com/go-co-op/gocron/v2"var (
// Scheduler / executor errors
ErrStopExecutorTimedOut = errors.New("gocron: timed out waiting for executor to stop")
ErrStopJobsTimedOut = errors.New("gocron: timed out waiting for jobs to finish")
ErrStopSchedulerTimedOut = errors.New("gocron: timed out waiting for scheduler to stop")
// Job not found / run errors
ErrJobNotFound = errors.New("gocron: job not found")
ErrJobRunNowFailed = errors.New("gocron: Job: RunNow: scheduler unreachable")
// NewJob task validation errors
ErrNewJobTaskNil = errors.New("gocron: NewJob: Task must not be nil")
ErrNewJobTaskNotFunc = errors.New("gocron: NewJob: Task.Function must be of kind reflect.Func")
ErrNewJobWrongNumberOfParameters = errors.New("gocron: NewJob: Number of provided parameters does not match expected")
ErrNewJobWrongTypeOfParameters = errors.New("gocron: NewJob: Type of provided parameters does not match expected")
// Panic recovery
ErrPanicRecovered = errors.New("gocron: panic recovered")
// CronJob errors
ErrCronJobInvalid = errors.New("gocron: CronJob: invalid crontab")
ErrCronJobParse = errors.New("gocron: CronJob: crontab parse failure")
// DurationJob errors
ErrDurationJobIntervalZero = errors.New("gocron: DurationJob: time interval is 0")
ErrDurationJobIntervalNegative = errors.New("gocron: DurationJob: time interval must be greater than 0")
// DurationRandomJob errors
ErrDurationRandomJobPositive = errors.New("gocron: DurationRandomJob: minimum and maximum durations must be greater than 0")
ErrDurationRandomJobMinMax = errors.New("gocron: DurationRandomJob: minimum duration must be less than maximum duration")
// DailyJob errors
ErrDailyJobAtTimeNil = errors.New("gocron: DailyJob: atTime within atTimes must not be nil")
ErrDailyJobAtTimesNil = errors.New("gocron: DailyJob: atTimes must not be nil")
ErrDailyJobHours = errors.New("gocron: DailyJob: atTimes hours must be between 0 and 23 inclusive")
ErrDailyJobZeroInterval = errors.New("gocron: DailyJob: interval must be greater than 0")
ErrDailyJobMinutesSeconds = errors.New("gocron: DailyJob: atTimes minutes and seconds must be between 0 and 59 inclusive")
// WeeklyJob errors
ErrWeeklyJobAtTimeNil = errors.New("gocron: WeeklyJob: atTime within atTimes must not be nil")
ErrWeeklyJobAtTimesNil = errors.New("gocron: WeeklyJob: atTimes must not be nil")
ErrWeeklyJobDaysOfTheWeekNil = errors.New("gocron: WeeklyJob: daysOfTheWeek must not be nil")
ErrWeeklyJobHours = errors.New("gocron: WeeklyJob: atTimes hours must be between 0 and 23 inclusive")
ErrWeeklyJobZeroInterval = errors.New("gocron: WeeklyJob: interval must be greater than 0")
ErrWeeklyJobMinutesSeconds = errors.New("gocron: WeeklyJob: atTimes minutes and seconds must be between 0 and 59 inclusive")
// MonthlyJob errors
ErrMonthlyJobDays = errors.New("gocron: MonthlyJob: daysOfTheMonth must be between 31 and -31 inclusive, and not 0")
ErrMonthlyJobAtTimeNil = errors.New("gocron: MonthlyJob: atTime within atTimes must not be nil")
ErrMonthlyJobAtTimesNil = errors.New("gocron: MonthlyJob: atTimes must not be nil")
ErrMonthlyJobDaysNil = errors.New("gocron: MonthlyJob: daysOfTheMonth must not be nil")
ErrMonthlyJobHours = errors.New("gocron: MonthlyJob: atTimes hours must be between 0 and 23 inclusive")
ErrMonthlyJobZeroInterval = errors.New("gocron: MonthlyJob: interval must be greater than 0")
ErrMonthlyJobMinutesSeconds = errors.New("gocron: MonthlyJob: atTimes minutes and seconds must be between 0 and 59 inclusive")
// OneTimeJob errors
ErrOneTimeJobStartDateTimePast = errors.New("gocron: OneTimeJob: start must not be in the past")
// Event listener errors
ErrEventListenerFuncNil = errors.New("gocron: eventListenerFunc must not be nil")
// WithStartAt / WithStopAt errors
ErrWithStartDateTimePast = errors.New("gocron: WithStartDateTime: start must not be in the past")
ErrWithStartDateTimePastZero = errors.New("gocron: WithStartDateTime: start must not be zero")
ErrWithStopDateTimePast = errors.New("gocron: WithStopDateTime: end must not be in the past")
ErrStartTimeLaterThanEndTime = errors.New("gocron: WithStartDateTime: start must not be later than end")
ErrStopTimeEarlierThanStartTime = errors.New("gocron: WithStopDateTime: end must not be earlier than start")
// SchedulerOption validation errors
ErrWithClockNil = errors.New("gocron: WithClock: clock must not be nil")
ErrWithContextNil = errors.New("gocron: WithContext: context must not be nil")
ErrWithDistributedElectorNil = errors.New("gocron: WithDistributedElector: elector must not be nil")
ErrWithDistributedLockerNil = errors.New("gocron: WithDistributedLocker: locker must not be nil")
ErrWithDistributedJobLockerNil = errors.New("gocron: WithDistributedJobLocker: locker must not be nil")
ErrWithIdentifierNil = errors.New("gocron: WithIdentifier: identifier must not be nil")
ErrWithLimitConcurrentJobsZero = errors.New("gocron: WithLimitConcurrentJobs: limit must be greater than 0")
ErrWithLimitedRunsZero = errors.New("gocron: WithLimitedRuns: limit must be greater than 0")
ErrWithLocationNil = errors.New("gocron: WithLocation: location must not be nil")
ErrWithLoggerNil = errors.New("gocron: WithLogger: logger must not be nil")
ErrWithMonitorNil = errors.New("gocron: WithMonitor: monitor must not be nil")
ErrWithNameEmpty = errors.New("gocron: WithName: name must not be empty")
ErrWithSchedulerMonitorNil = errors.New("gocron: WithSchedulerMonitor: scheduler monitor cannot be nil")
ErrSchedulerMonitorNil = errors.New("gocron: WithSchedulerMonitor: monitor must not be nil")
ErrWithStopTimeoutZeroOrNegative = errors.New("gocron: WithStopTimeout: timeout must be greater than 0")
)j, err := s.NewJob(
gocron.CronJob("invalid", false),
gocron.NewTask(myFunc),
)
if err != nil {
if errors.Is(err, gocron.ErrCronJobParse) {
log.Fatal("invalid cron expression")
}
log.Fatal("failed to create job:", err)
}ErrStopExecutorTimedOut
Shutdown(), StopJobs()WithStopTimeout)ErrStopJobsTimedOut
StopJobs()ErrStopSchedulerTimedOut
Shutdown(), StopJobs()ErrJobNotFound
RemoveJob(), Job.LastRun(), Job.NextRun(), Job.NextRuns()ErrJobRunNowFailed
Job.RunNow()RunNow()ErrNewJobTaskNil
NewJob(), Update()Task argument is nilTask created with NewTask()ErrNewJobTaskNotFunc
NewJob(), Update()Task.Function is not a function (e.g., a struct, int, etc.)NewTask()ErrNewJobWrongNumberOfParameters
NewJob(), Update()NewTask() doesn't match function signatureErrNewJobWrongTypeOfParameters
NewJob(), Update()NewTask() don't match function signatureErrPanicRecovered
AfterJobRunsWithPanic event listenerErrCronJobInvalid
NewJob() with CronJob()ErrCronJobParse
NewJob() with CronJob()withSeconds flag)Example valid expressions:
"0 9 * * *" (9 AM daily)"30 0 9 * * *" (9:00:30 AM daily, withSeconds=true)"TZ=America/Chicago 0 9 * * *"ErrDurationJobIntervalZero
NewJob() with DurationJob(0)ErrDurationJobIntervalNegative
NewJob() with DurationJob(negative)ErrDurationRandomJobPositive
NewJob() with DurationRandomJob()ErrDurationRandomJobMinMax
NewJob() with DurationRandomJob()minDuration < maxDurationErrDailyJobZeroInterval
NewJob() with DailyJob(0, ...)ErrDailyJobAtTimesNil
NewJob() with DailyJob(..., nil)atTimes is nilNewAtTimes()ErrDailyJobAtTimeNil
NewJob() with DailyJob()atTime values in atTimes is nilNewAtTime()ErrDailyJobHours
NewJob() with DailyJob()ErrDailyJobMinutesSeconds
NewJob() with DailyJob()ErrWeeklyJobZeroInterval
NewJob() with WeeklyJob(0, ...)ErrWeeklyJobDaysOfTheWeekNil
NewJob() with WeeklyJob(..., nil, ...)daysOfTheWeek is nilNewWeekdays()ErrWeeklyJobAtTimesNil
NewJob() with WeeklyJob(..., ..., nil)atTimes is nilNewAtTimes()ErrWeeklyJobAtTimeNil
NewJob() with WeeklyJob()atTime values in atTimes is nilNewAtTime()ErrWeeklyJobHours
NewJob() with WeeklyJob()ErrWeeklyJobMinutesSeconds
NewJob() with WeeklyJob()ErrMonthlyJobZeroInterval
NewJob() with MonthlyJob(0, ...)ErrMonthlyJobDaysNil
NewJob() with MonthlyJob(..., nil, ...)daysOfTheMonth is nilNewDaysOfTheMonth()ErrMonthlyJobDays
NewJob() with MonthlyJob()ErrMonthlyJobAtTimesNil
NewJob() with MonthlyJob(..., ..., nil)atTimes is nilNewAtTimes()ErrMonthlyJobAtTimeNil
NewJob() with MonthlyJob()atTime values in atTimes is nilNewAtTime()ErrMonthlyJobHours
NewJob() with MonthlyJob()ErrMonthlyJobMinutesSeconds
NewJob() with MonthlyJob()ErrOneTimeJobStartDateTimePast
NewJob() with OneTimeJob()OneTimeJobStartImmediately()ErrEventListenerFuncNil
WithEventListeners() during NewJob()ErrWithStartDateTimePast
WithStartAt(WithStartDateTime(...))WithStartDateTimePast() to allow backdatingErrWithStartDateTimePastZero
WithStartAt(WithStartDateTimePast(...))time.Time{})ErrWithStopDateTimePast
WithStopAt(WithStopDateTime(...))ErrStartTimeLaterThanEndTime
NewJob() when both WithStartAt and WithStopAt are setErrStopTimeEarlierThanStartTime
NewJob() when both WithStartAt and WithStopAt are setErrWithClockNil
NewScheduler(WithClock(nil))clockwork.Clock (typically for testing)ErrWithContextNil
WithContext(nil)ErrWithDistributedElectorNil
NewScheduler(WithDistributedElector(nil))Elector implementationErrWithDistributedLockerNil
NewScheduler(WithDistributedLocker(nil))Locker implementationErrWithDistributedJobLockerNil
WithDistributedJobLocker(nil)Locker implementationErrWithIdentifierNil
WithIdentifier(uuid.Nil)ErrWithLimitConcurrentJobsZero
NewScheduler(WithLimitConcurrentJobs(0, ...))ErrWithLimitedRunsZero
WithLimitedRuns(0)ErrWithLocationNil
NewScheduler(WithLocation(nil))*time.LocationErrWithLoggerNil
NewScheduler(WithLogger(nil))Logger implementationErrWithMonitorNil
NewScheduler(WithMonitor(nil)) or NewScheduler(WithMonitorStatus(nil))Monitor or MonitorStatus implementationErrWithNameEmpty
WithName("")ErrSchedulerMonitorNil / ErrWithSchedulerMonitorNil
NewScheduler(WithSchedulerMonitor(nil))SchedulerMonitor implementationErrWithStopTimeoutZeroOrNegative
NewScheduler(WithStopTimeout(0)) or NewScheduler(WithStopTimeout(-1))| Error | Returned by |
|---|---|
ErrCronJobInvalid | NewJob with CronJob |
ErrCronJobParse | NewJob with CronJob |
ErrDailyJob* | NewJob with DailyJob |
ErrDurationJobInterval* | NewJob with DurationJob |
ErrDurationRandomJob* | NewJob with DurationRandomJob |
ErrEventListenerFuncNil | WithEventListeners (during NewJob) |
ErrJobNotFound | RemoveJob, Job.LastRun, Job.NextRun, Job.NextRuns |
ErrJobRunNowFailed | Job.RunNow |
ErrMonthlyJob* | NewJob with MonthlyJob |
ErrNewJobTask* | NewJob (task validation) |
ErrNewJobWrong* | NewJob (parameter validation) |
ErrOneTimeJobStartDateTimePast | NewJob with OneTimeJob |
ErrPanicRecovered | Internal executor (available via AfterJobRunsWithPanic) |
ErrStartTimeLaterThanEndTime | WithStartAt(WithStartDateTime(...)) |
ErrStopExecutorTimedOut | Shutdown, StopJobs |
ErrStopJobsTimedOut | StopJobs |
ErrStopSchedulerTimedOut | Shutdown, StopJobs |
ErrStopTimeEarlierThanStartTime | WithStopAt(WithStopDateTime(...)) |
ErrWeeklyJob* | NewJob with WeeklyJob |
ErrSchedulerMonitorNil | WithSchedulerMonitor |
ErrWith* | Corresponding SchedulerOption or JobOption |
j, err := s.NewJob(
gocron.CronJob("invalid cron", false),
gocron.NewTask(myFunc),
)
if errors.Is(err, gocron.ErrCronJobParse) {
log.Printf("Invalid cron expression: %v", err)
}j, _ := s.NewJob(gocron.DurationJob(time.Minute), gocron.NewTask(myFunc))
s.RemoveJob(j.ID())
// Later
nextRun, err := j.NextRun()
if errors.Is(err, gocron.ErrJobNotFound) {
log.Println("Job was removed")
}s, _ := gocron.NewScheduler(gocron.WithStopTimeout(5 * time.Second))
s.NewJob(...)
s.Start()
err := s.Shutdown()
if errors.Is(err, gocron.ErrStopSchedulerTimedOut) {
log.Println("Some jobs did not finish in time")
}// Function expects (string, int)
myFunc := func(s string, n int) { fmt.Println(s, n) }
// Wrong number of parameters
_, err := s.NewJob(
gocron.DurationJob(time.Minute),
gocron.NewTask(myFunc, "hello"), // missing second parameter
)
if errors.Is(err, gocron.ErrNewJobWrongNumberOfParameters) {
log.Println("Parameter count mismatch")
}
// Wrong type
_, err = s.NewJob(
gocron.DurationJob(time.Minute),
gocron.NewTask(myFunc, "hello", "world"), // second param should be int
)
if errors.Is(err, gocron.ErrNewJobWrongTypeOfParameters) {
log.Println("Parameter type mismatch")
}start := time.Now().Add(2 * time.Hour)
stop := time.Now().Add(1 * time.Hour)
_, err := s.NewJob(
gocron.DurationJob(time.Minute),
gocron.NewTask(myFunc),
gocron.WithStartAt(gocron.WithStartDateTime(start)),
gocron.WithStopAt(gocron.WithStopDateTime(stop)),
)
if errors.Is(err, gocron.ErrStartTimeLaterThanEndTime) {
log.Println("Start time must be before stop time")
}Install with Tessl CLI
npx tessl i tessl/golang-github-com-go-co-op-gocron-v2@2.19.1docs
api
examples
guides