Mercurial > gemma
changeset 4058:6c5c15b2fb64
Database errors have to be handled elsewhere than in imports, too
author | Tom Gottfried <tom@intevation.de> |
---|---|
date | Thu, 25 Jul 2019 09:12:53 +0200 |
parents | b79b60c0cc5a |
children | 07d853f9bf47 |
files | pkg/common/errors.go pkg/imports/bn.go pkg/imports/errors.go pkg/imports/fd.go pkg/imports/gm.go pkg/imports/sec.go pkg/imports/st.go pkg/imports/wa.go pkg/imports/wg.go pkg/imports/wx.go |
diffstat | 10 files changed, 93 insertions(+), 102 deletions(-) [+] |
line wrap: on
line diff
--- a/pkg/common/errors.go Thu Jul 25 08:16:34 2019 +0200 +++ b/pkg/common/errors.go Thu Jul 25 09:12:53 2019 +0200 @@ -4,12 +4,13 @@ // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // -// Copyright (C) 2018 by via donau +// Copyright (C) 2018, 2019 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> +// * Tom Gottfried <tom.gottfried@intevation.de> package common @@ -17,6 +18,8 @@ "errors" "fmt" "strings" + + "github.com/jackc/pgx" ) // ToError concats a slice of errors to a single error. @@ -30,3 +33,67 @@ } return errors.New(b.String()) } + +// Handle PostgreSQL error codes +func HandlePGError(err error) error { + switch e := err.(type) { + case pgx.PgError: + return dbError(e) + } + return err +} + +const ( + notNullViolation = "23502" + foreignKeyViolation = "23503" + violatesRowLevelSecurity = "42501" + noDataFound = "P0002" +) + +type dbError pgx.PgError + +func (err dbError) Error() string { + switch err.Code { + case notNullViolation: + switch err.SchemaName { + case "waterway": + switch err.TableName { + case "gauges": + switch err.ColumnName { + case "objname": + return "Missing objname" + case "geom": + return "Missing lat/lon" + case "zero_point": + return "Missing zeropoint" + } + } + } + case foreignKeyViolation: + switch err.SchemaName { + case "waterway": + switch err.TableName { + case "gauge_measurements", "gauge_predictions", "bottlenecks": + switch err.ConstraintName { + case "gauge_key": + return "Referenced gauge with matching temporal validity not available" + } + } + } + case noDataFound: + // Most recent line from stacktrace contains name of failed function + recent := strings.SplitN(err.Where, "\n", 1)[0] + switch { + case strings.Contains(recent, "isrsrange_points"): + return "No distance mark found for at least one given ISRS Location Code" + case strings.Contains(recent, "isrsrange_axis"): + return "No contiguous axis found between given ISRS Location Codes" + case strings.Contains(recent, "isrsrange_area"): + return "No area around axis between given ISRS Location Codes" + } + + case violatesRowLevelSecurity: + return "Could not save: Data outside the area of responsibility." + } + return "Unexpected database error: " + err.Message +}
--- a/pkg/imports/bn.go Thu Jul 25 08:16:34 2019 +0200 +++ b/pkg/imports/bn.go Thu Jul 25 09:12:53 2019 +0200 @@ -24,6 +24,7 @@ "strings" "time" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/soap/ifbn" "github.com/jackc/pgx/pgtype" ) @@ -590,7 +591,7 @@ ) } if err != nil { - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) return nil } defer bns.Close() @@ -602,7 +603,7 @@ bnIds = append(bnIds, nid) } if err := bns.Err(); err != nil { - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) return nil } if len(bnIds) == 0 { @@ -619,7 +620,7 @@ &validity, &pgBnIds, ); err != nil { - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) if err2 := tx.Rollback(); err2 != nil { return err2 } @@ -632,7 +633,7 @@ bn.Bottleneck_id, validity, ); err != nil { - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) if err2 := tx.Rollback(); err2 != nil { return err2 } @@ -669,7 +670,7 @@ &pgMaterials, ); err != nil { feedback.Warn("Failed to insert riverbed materials") - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) return nil } }
--- a/pkg/imports/errors.go Thu Jul 25 08:16:34 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -// This is Free Software under GNU Affero General Public License v >= 3.0 -// without warranty, see README.md and license for details. -// -// SPDX-License-Identifier: AGPL-3.0-or-later -// License-Filename: LICENSES/AGPL-3.0.txt -// -// Copyright (C) 2019 by via donau -// – Österreichische Wasserstraßen-Gesellschaft mbH -// Software engineering by Intevation GmbH -// -// Author(s): -// * Tom Gottfried <tom.gottfried@intevation.de> - -package imports - -import ( - "strings" - - "github.com/jackc/pgx" -) - -func handleError(err error) error { - switch e := err.(type) { - case pgx.PgError: - return dbError(e) - } - return err -} - -// Handle PostgreSQL error codes -const ( - notNullViolation = "23502" - foreignKeyViolation = "23503" - violatesRowLevelSecurity = "42501" - noDataFound = "P0002" -) - -type dbError pgx.PgError - -func (err dbError) Error() string { - switch err.Code { - case notNullViolation: - switch err.SchemaName { - case "waterway": - switch err.TableName { - case "gauges": - switch err.ColumnName { - case "objname": - return "Missing objname" - case "geom": - return "Missing lat/lon" - case "zero_point": - return "Missing zeropoint" - } - } - } - case foreignKeyViolation: - switch err.SchemaName { - case "waterway": - switch err.TableName { - case "gauge_measurements", "gauge_predictions", "bottlenecks": - switch err.ConstraintName { - case "gauge_key": - return "Referenced gauge with matching temporal validity not available" - } - } - } - case noDataFound: - // Most recent line from stacktrace contains name of failed function - recent := strings.SplitN(err.Where, "\n", 1)[0] - switch { - case strings.Contains(recent, "isrsrange_points"): - return "No distance mark found for at least one given ISRS Location Code" - case strings.Contains(recent, "isrsrange_axis"): - return "No contiguous axis found between given ISRS Location Codes" - case strings.Contains(recent, "isrsrange_area"): - return "No area around axis between given ISRS Location Codes" - } - - case violatesRowLevelSecurity: - return "Could not save: Data outside the area of responsibility." - } - return "Unexpected database error: " + err.Message -}
--- a/pkg/imports/fd.go Thu Jul 25 08:16:34 2019 +0200 +++ b/pkg/imports/fd.go Thu Jul 25 09:12:53 2019 +0200 @@ -21,6 +21,7 @@ "io" "time" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/misc" "gemma.intevation.de/gemma/pkg/wfs" ) @@ -310,7 +311,7 @@ // ignore -> filtered by responsibility_areas continue features case err != nil: - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) continue features } // Store for potential later removal.
--- a/pkg/imports/gm.go Thu Jul 25 08:16:34 2019 +0200 +++ b/pkg/imports/gm.go Thu Jul 25 09:12:53 2019 +0200 @@ -24,6 +24,7 @@ "strings" "time" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/models" "gemma.intevation.de/gemma/pkg/soap/nts" "github.com/jackc/pgx/pgtype" @@ -456,7 +457,7 @@ case err == sql.ErrNoRows: // thats expected, nothing to do case err != nil: - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) default: newP++ } @@ -487,7 +488,7 @@ case err == sql.ErrNoRows: // thats expected, nothing to do case err != nil: - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) default: newM++ }
--- a/pkg/imports/sec.go Thu Jul 25 08:16:34 2019 +0200 +++ b/pkg/imports/sec.go Thu Jul 25 09:12:53 2019 +0200 @@ -18,6 +18,7 @@ "database/sql" "time" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/models" ) @@ -181,7 +182,7 @@ sec.Source, sec.Tolerance, ).Scan(&id); err != nil { - return nil, handleError(err) + return nil, common.HandlePGError(err) } if err := track(ctx, tx, importID, "waterway.sections", id); err != nil {
--- a/pkg/imports/st.go Thu Jul 25 08:16:34 2019 +0200 +++ b/pkg/imports/st.go Thu Jul 25 09:12:53 2019 +0200 @@ -19,6 +19,7 @@ "errors" "time" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/models" ) @@ -202,7 +203,7 @@ st.Source, st.Tolerance, ).Scan(&id); err != nil { - return nil, handleError(err) + return nil, common.HandlePGError(err) } // store the associated countries.
--- a/pkg/imports/wa.go Thu Jul 25 08:16:34 2019 +0200 +++ b/pkg/imports/wa.go Thu Jul 25 09:12:53 2019 +0200 @@ -24,6 +24,7 @@ "strconv" "time" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/wfs" ) @@ -246,7 +247,7 @@ outside++ // ignore -> filtered by responsibility_areas case err != nil: - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) default: features++ }
--- a/pkg/imports/wg.go Thu Jul 25 08:16:34 2019 +0200 +++ b/pkg/imports/wg.go Thu Jul 25 09:12:53 2019 +0200 @@ -21,6 +21,7 @@ "github.com/jackc/pgx/pgtype" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/models" "gemma.intevation.de/gemma/pkg/soap/erdms" ) @@ -326,7 +327,7 @@ ).Scan(&isNew) switch { case err != nil: - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) if err2 := tx.Rollback(); err2 != nil { return nil, err2 } @@ -351,7 +352,7 @@ source, time.Time(*dr.Lastupdate), ); err != nil { - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) if err2 := tx.Rollback(); err2 != nil { return nil, err2 } @@ -388,7 +389,7 @@ unchanged++ continue case err2 != nil: - feedback.Warn(handleError(err2).Error()) + feedback.Warn(common.HandlePGError(err2).Error()) if err3 := tx.Rollback(); err3 != nil { return nil, err3 } @@ -435,7 +436,7 @@ code.String(), &validity, ); err != nil { - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) if err2 := tx.Rollback(); err2 != nil { return nil, err2 } @@ -483,7 +484,7 @@ string(**wl.level), int64(**wl.value), ); err != nil { - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) tx.Rollback() continue }
--- a/pkg/imports/wx.go Thu Jul 25 08:16:34 2019 +0200 +++ b/pkg/imports/wx.go Thu Jul 25 09:12:53 2019 +0200 @@ -23,6 +23,7 @@ "io" "time" + "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/wfs" ) @@ -320,7 +321,7 @@ // ignore -> filtered by responsibility_areas return nil case err != nil: - feedback.Warn(handleError(err).Error()) + feedback.Warn(common.HandlePGError(err).Error()) default: *features++ }