openmeter / billing /errors.go
Leon4gr45's picture
Upload folder using huggingface_hub (part 2)
5a22efd verified
Raw
History Blame Contribute Delete
9.89 kB
package billing
import (
"fmt"
"github.com/openmeterio/openmeter/openmeter/app"
)
var (
// We want to return the invoice regardless of the validation issues, as invoices can have issues at numerous
// levels (e.g. missing default profile, missing customer override, missing billing profile, provider issues, etc.).
//
// We also return the validation issues. By adding codes to the validation issues, it will be easier for the clients (e.g. frontend) to handle the specific errors
// without having to resort to string matching.
//
// Given that invoicing depends on the billing and customer override service, we need to have these error types in place for
// all.
ErrDefaultProfileNotFound = NewValidationError("default_profile_not_found", "default profile not found")
ErrProfileNotFound = NewValidationError("profile_not_found", "profile not found")
ErrProfileAlreadyDeleted = NewValidationError("profile_already_deleted", "profile already deleted")
ErrProfileReferencedByOverrides = NewValidationError("profile_referenced", "profile is referenced by customer overrides")
ErrDefaultProfileCannotBeDeleted = NewValidationError("default_profile_cannot_be_deleted", "default profile cannot be deleted")
ErrDefaultProfileCannotBeUnset = NewValidationError("default_profile_cannot_be_unset", "default profile cannot be unset")
ErrCustomerOverrideNotFound = NewValidationError("customer_override_not_found", "customer override not found")
ErrCustomerOverrideAlreadyDeleted = NewValidationError("customer_override_deleted", "customer override already deleted")
ErrCustomerNotFound = NewValidationError("customer_not_found", "customer not found")
ErrCustomerDeleted = NewValidationError("customer_deleted", "customer has been deleted")
ErrFieldRequired = NewValidationError("field_required", "field is required")
ErrFieldMustBePositive = NewValidationError("field_must_be_positive", "field must be positive")
ErrFieldMustBePositiveOrZero = NewValidationError("field_must_be_positive_or_zero", "field must be positive or zero")
ErrInvoiceCannotAdvance = NewValidationError("invoice_cannot_advance", "invoice cannot advance")
ErrInvoiceCannotBeEdited = NewValidationError("invoice_cannot_be_edited", "invoice cannot be edited in the current state")
ErrInvoiceActionNotAvailable = NewValidationError("invoice_action_not_available", "invoice action not available")
ErrInvoiceProgressiveBillingNotSupported = NewValidationError("invoice_progressive_billing_not_supported", "progressive billing is not supported")
ErrInvoiceLinesNotBillable = NewValidationError("invoice_lines_not_billable", "invoice lines are not billable")
ErrInvoiceEmpty = NewValidationError("invoice_empty", "invoice is empty")
ErrInvoiceNotFound = NewValidationError("invoice_not_found", "invoice not found")
ErrInvoiceDeleteFailed = NewValidationError("invoice_delete_failed", "invoice delete failed")
ErrInvoiceCannotDeleteGathering = NewValidationError("invoice_cannot_delete_gathering", "gathering invoices cannot be deleted, please delete the upcoming lines instead")
ErrInvoiceLineFeatureHasNoMeters = NewValidationError("invoice_line_feature_has_no_meters", "usage based invoice line: feature has no meters")
ErrInvoiceLineVolumeSplitNotSupported = NewValidationError("invoice_line_graduated_split_not_supported", "graduated tiered pricing is not supported for split periods")
ErrInvoiceLineNoTiers = NewValidationError("invoice_line_no_tiers", "usage based invoice line: no tiers found")
ErrInvoiceLineMissingOpenEndedTier = NewValidationError("invoice_line_missing_open_ended_tier", "usage based invoice line: missing open ended tier")
ErrInvoiceLineDeleteInvalidStatus = NewValidationError("invoice_line_delete_invalid_status", "invoice line cannot be deleted in the current state (only valid lines can be deleted)")
ErrInvoiceLineNoPeriodChangeForSplitLine = NewValidationError("invoice_line_no_period_change_for_split_line", "invoice line period cannot be changed for split lines")
ErrInvoiceLineNoPeriodChangeForSubscriptionManagedLine = NewValidationError("invoice_line_no_period_change_for_subscription_managed_line", "invoice line period cannot be changed for subscription managed lines")
ErrInvoiceLineProgressiveBillingUsageDiscountUpdateForbidden = NewValidationError("invoice_line_progressive_billing_usage_discount_update_forbidden", "usage discount cannot be updated on a partially invoiced line")
ErrInvoiceCreateNoLines = NewValidationError("invoice_create_no_lines", "the new invoice would have no lines")
ErrInvoiceCreateUBPLineCustomerUsageAttributionInvalid = NewValidationError("invoice_create_ubp_line_customer_has_no_subjects", "creating an usage based line: customer usage attribution is invalid")
ErrInvoiceCreateUBPLinePeriodIsEmpty = NewValidationError("invoice_create_ubp_line_period_is_empty", "creating an usage based line: truncated period is empty")
ErrInvoiceLineCurrencyMismatch = NewValidationError("invoice_line_currency_mismatch", "invoice line currency mismatch")
ErrInvoiceLineSnapshotFailed = NewValidationError("invoice_line_snapshot_failed", "invoice line snapshot failed")
ErrInvoiceDiscountInvalidLineReference = NewValidationError("invoice_discount_invalid_line_reference", "invoice discount references non-existing line")
ErrInvoiceDiscountNoWildcardDiscountOnGatheringInvoices = NewValidationError("invoice_discount_no_wildcard_discount_on_gathering_invoices", "wildcard discount on gathering invoices is not allowed")
ErrNamespaceLocked = NewValidationError("namespace_locked", "namespace is locked")
ErrInvoiceLineCreditsNotConsumedFully = NewValidationError("invoice_line_credits_not_consumed_fully", "credits not consumed fully")
ErrCannotUpdateChargeManagedLine = NewValidationError("cannot_update_charge_managed_line", "cannot update charge managed lines, please update the charge instead")
ErrCannotEditProgressivelyBilledUsageBasedLine = NewValidationError("cannot_edit_progressively_billed_usagebased_line", "cannot edit usagebased items that are progressively billed, update the charge instead")
ErrInvoiceLineFeatureKeyEditNotSupported = NewValidationError("invoice_line_feature_key_edit_not_supported", "feature key editing is not supported for charge-managed invoice lines, please delete the charge instead")
ErrInvoiceLineTaxConfigEditNotSupported = NewValidationError("invoice_line_tax_config_edit_not_supported", "tax config editing is not supported for charge-managed invoice lines, please delete the charge instead")
ErrInvoiceLineZeroAmountDeleteInstead = NewValidationError("invoice_line_zero_amount_delete_instead", "invoice line amount cannot be updated to zero, please delete the line instead")
ErrInvoiceLineZeroAmountCreate = NewValidationError("invoice_line_zero_amount_create", "creating zero amount flat fee invoice lines is not supported")
)
const (
ImmutableInvoiceHandlingNotSupportedErrorCode = "immutable_invoice_handling_not_supported"
)
var _ error = (*NotFoundError)(nil)
const (
EntityCustomerOverride = "BillingCustomerOverride"
EntityCustomer = "Customer"
EntityDefaultProfile = "DefaultBillingProfile"
EntityInvoice = "Invoice"
EntityInvoiceLine = "InvoiceLine"
)
type NotFoundError struct {
ID string
Entity string
Err error
}
func (e NotFoundError) Error() string {
// ID can be empty for default profiles
if e.ID == "" {
return e.Err.Error()
}
return fmt.Sprintf("%s [%s/%s]", e.Err, e.Entity, e.ID)
}
func (e NotFoundError) Unwrap() error {
return e.Err
}
type genericError struct {
Err error
}
func EncodeValidationIssues[T error](err T) map[string]interface{} {
validationIssues, _ := ToValidationIssues(err)
if len(validationIssues) == 0 {
return map[string]interface{}{}
}
// For HTTP calls we are usually interested in the first issue
// so we return it as the main error
out := validationIssues[0].EncodeAsErrorExtension()
if len(validationIssues) > 1 {
out["additionalIssues"] = validationIssues[1:]
}
return out
}
var _ error = (*ValidationError)(nil)
type ValidationError genericError
func (e ValidationError) Error() string {
return e.Err.Error()
}
func (e ValidationError) Unwrap() error {
return e.Err
}
var _ error = (*UpdateAfterDeleteError)(nil)
type UpdateAfterDeleteError genericError
func (e UpdateAfterDeleteError) Error() string {
return e.Err.Error()
}
func (e UpdateAfterDeleteError) Unwrap() error {
return e.Err
}
// AppError represents an error when interacting with an app.
var _ error = (*AppError)(nil)
type AppError struct {
AppID app.AppID
AppType app.AppType
Err error
}
func (e AppError) Error() string {
return fmt.Sprintf("app %s type with id %s in namespace %s: %s", e.AppType, e.AppID.ID, e.AppID.Namespace, e.Err.Error())
}
// ErrSnapshotInvalidDatabaseState is returned when the database state is invalid for snapshotting the line quantity.
// This can happen if the feature or meter is not found. In such cases we should transition the invoice to
// draft.invalid state.
type ErrSnapshotInvalidDatabaseState struct {
Err error
}
func (e ErrSnapshotInvalidDatabaseState) Error() string {
return fmt.Sprintf("snapshotting line quantity: %s", e.Err.Error())
}
func (e ErrSnapshotInvalidDatabaseState) Unwrap() error {
return e.Err
}