errors.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package domain
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/nicksnyder/go-i18n/v2/i18n"
  6. )
  7. type ErrorKind = string
  8. var NoError = i18n.Message{ID: "error.none", Other: "No error"}
  9. var Unimplemented = i18n.Message{ID: "error.unimplemented", Other: "Not yet implemented"}
  10. var ShortNotCreated = i18n.Message{ID: "error.short_not_created", Other: "Short URL not created for a new target"}
  11. var TargetInvalid = i18n.Message{ID: "error.target_invalid", Other: "Target invalid"}
  12. var ShortNotFound = i18n.Message{ID: "error.short_not_found", Other: "Short URL not defined"}
  13. var TargetBlocked = i18n.Message{ID: "error.target_blocked", Other: "Target blocked"}
  14. var TargetCensored = i18n.Message{ID: "error.target_censored", Other: "Target unavailable for legal reasons"}
  15. var StorageRead = i18n.Message{ID: "error.storage_read", Other: "Storage read error"}
  16. var StorageWrite = i18n.Message{ID: "error.storage_write", Other: "Storage write error"}
  17. var StorageUnspecified = i18n.Message{ID: "error.storage_unspecified", Other: "Storage unspecified error"}
  18. var ErrorMessages = map[ErrorKind]i18n.Message{
  19. NoError.ID: NoError,
  20. Unimplemented.ID: Unimplemented,
  21. ShortNotCreated.ID: ShortNotCreated,
  22. ShortNotFound.ID: ShortNotFound,
  23. TargetBlocked.ID: TargetBlocked,
  24. TargetCensored.ID: TargetCensored,
  25. TargetInvalid.ID: TargetInvalid,
  26. StorageRead.ID: StorageRead,
  27. StorageWrite.ID: StorageWrite,
  28. StorageUnspecified.ID: StorageUnspecified,
  29. }
  30. // Error instances are created localized by MakeError(kind, detail, localizer),
  31. // so they do not need to support localization themselves.
  32. type Error struct {
  33. error
  34. Kind ErrorKind
  35. }
  36. // MakeError creates a localized error instance, ready to print.
  37. func MakeError(l *i18n.Localizer, kind ErrorKind, detail string) Error {
  38. var message string
  39. // Support errors with a localizer.
  40. if l == nil {
  41. s := ErrorMessages[kind].Other
  42. var e error
  43. if detail != "" {
  44. e = errors.New(fmt.Sprintf("%s: %s", s, detail))
  45. } else {
  46. e = errors.New(s)
  47. }
  48. err := Error{
  49. Kind: kind,
  50. error: e,
  51. }
  52. return err
  53. }
  54. if len(detail) == 0 {
  55. message = l.MustLocalize(&i18n.LocalizeConfig{
  56. MessageID: ErrorMessages[kind].ID,
  57. })
  58. } else {
  59. em, ok := ErrorMessages[kind]
  60. if !ok {
  61. em = i18n.Message{
  62. ID: "error.dynamic",
  63. Description: "This is an unplanned error generated on the fly from details. It should be replaced",
  64. }
  65. }
  66. localizedKind := l.MustLocalize(&i18n.LocalizeConfig{
  67. DefaultMessage: &em,
  68. MessageID: em.ID,
  69. })
  70. message = l.MustLocalize(&i18n.LocalizeConfig{
  71. DefaultMessage: &i18n.Message{
  72. ID: "error.error_format",
  73. Description: "The format for errors",
  74. One: "{.Kind}: {.Detail}",
  75. LeftDelim: "{",
  76. RightDelim: "}",
  77. },
  78. TemplateData: map[string]string{
  79. "Kind": localizedKind,
  80. "Detail": detail,
  81. },
  82. PluralCount: 1,
  83. })
  84. }
  85. return Error{
  86. Kind: kind,
  87. error: errors.New(message),
  88. }
  89. }