better error handling for User.
Adding an endpoint that allows user to create background job errors.
This commit is contained in:
parent
efd2fb3655
commit
ac5359c332
|
@ -14,6 +14,7 @@ type BackgroundJob struct {
|
|||
UserID uuid.UUID `json:"user_id"`
|
||||
|
||||
JobType pkg.BackgroundJobType `json:"job_type"`
|
||||
//this should be JSON encoded data from BackgroundJobSyncData or
|
||||
Data datatypes.JSON `gorm:"column:data;type:text;serializer:json" json:"data,omitempty"`
|
||||
JobStatus pkg.BackgroundJobStatus `json:"job_status"`
|
||||
LockedTime *time.Time `json:"locked_time"`
|
||||
|
|
|
@ -239,6 +239,46 @@ func ListBackgroundJobs(c *gin.Context) {
|
|||
c.JSON(http.StatusOK, gin.H{"success": true, "data": backgroundJobs})
|
||||
}
|
||||
|
||||
// CreateBackgroundJobError this function is used to store error data related to a Source/Provider connection operation that fails in the client-side
|
||||
// - client errors occur when the OAuth provider sends back an error message (error, error_description query string parameters) or when the code -> access token swap results in an error.
|
||||
// - server side errors occur for a number of reasons (unable to initialize client, unable to store crednetial in db, unable to sync 1 or more FHIR resources from a patient's medical record)
|
||||
func CreateBackgroundJobError(c *gin.Context) {
|
||||
|
||||
logger := c.MustGet(pkg.ContextKeyTypeLogger).(*logrus.Entry)
|
||||
databaseRepo := c.MustGet(pkg.ContextKeyTypeDatabase).(database.DatabaseRepository)
|
||||
|
||||
var payload models.BackgroundJobSyncData
|
||||
if err := c.ShouldBindJSON(&payload); err != nil {
|
||||
logger.Errorln("An error occurred while parsing error data", err)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"success": false})
|
||||
return
|
||||
}
|
||||
|
||||
//override the job type to be an error
|
||||
errJsonData, err := json.MarshalIndent(payload, "", " ")
|
||||
if err != nil {
|
||||
logger.Errorln("An error occurred re-encoding error data", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
|
||||
return
|
||||
}
|
||||
now := time.Now()
|
||||
backgroundJob := models.BackgroundJob{
|
||||
JobType: pkg.BackgroundJobTypeSync,
|
||||
JobStatus: pkg.BackgroundJobStatusFailed,
|
||||
DoneTime: &now,
|
||||
LockedTime: &now,
|
||||
Data: errJsonData,
|
||||
}
|
||||
|
||||
err = databaseRepo.CreateBackgroundJob(c, &backgroundJob)
|
||||
if err != nil {
|
||||
logger.Errorln("An error occurred while creating background job to store client-side error data", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"success": false})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"success": true})
|
||||
}
|
||||
|
||||
// Utilities
|
||||
|
||||
func GetBackgroundContext(ginContext *gin.Context) context.Context {
|
||||
|
|
|
@ -89,9 +89,12 @@ func CreateReconnectSource(c *gin.Context) {
|
|||
|
||||
summary, err := BackgroundJobSyncResources(GetBackgroundContext(c), logger, databaseRepo, &sourceCred)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("an error occurred while starting initial sync: %w", err)
|
||||
logger.Errorln(err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": err.Error()})
|
||||
//errors from the background job will be wrapped and stored in the database, lets just return a generic error
|
||||
// this is also important because these errors:
|
||||
// 1. are not user facing - longer/scarier for users, and may show information that they are not equipped to resolve themselves.
|
||||
// 2. lots of duplicate text ("an error occurred while...") due to wrapping as the error bubbles up the codebase.
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "initial record sync failed. See background jobs page for more details"})
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -118,7 +121,11 @@ func SourceSync(c *gin.Context) {
|
|||
if err != nil {
|
||||
err := fmt.Errorf("an error occurred while syncing resources: %w", err)
|
||||
logger.Errorln(err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": err.Error()})
|
||||
//errors from the background job will be wrapped and stored in the database, lets just return a generic error
|
||||
// this is also important because these errors:
|
||||
// 1. are not user facing - longer/scarier for users, and may show information that they are not equipped to resolve themselves.
|
||||
// 2. lots of duplicate text ("an error occurred while...") due to wrapping as the error bubbles up the codebase.
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "error": "record sync failed. See background jobs page for more details"})
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,7 @@ func (ae *AppEngine) Setup() (*gin.RouterGroup, *gin.Engine) {
|
|||
//secure.GET("/dashboard/:dashboardId", handler.GetDashboard)
|
||||
|
||||
secure.GET("/jobs", handler.ListBackgroundJobs)
|
||||
secure.POST("/jobs/error", handler.CreateBackgroundJobError)
|
||||
|
||||
secure.POST("/query", handler.QueryResourceFhir)
|
||||
|
||||
|
|
Loading…
Reference in New Issue