module ViewComponent class BaseError < StandardError def initialize super(self.class::MESSAGE) end end class DuplicateSlotContentError < StandardError MESSAGE = "It looks like a block was provided after calling `with_content` on COMPONENT, " \ "which means that ViewComponent doesn't know which content to use.\n\n" \ "To fix this issue, use either `with_content` or a block." def initialize(klass_name) super(MESSAGE.gsub("COMPONENT", klass_name.to_s)) end end class TemplateError < StandardError def initialize(errors) super(errors.join(", ")) end end class MultipleInlineTemplatesError < BaseError MESSAGE = "Inline templates can only be defined once per-component." end class MissingPreviewTemplateError < StandardError MESSAGE = "A preview template for example EXAMPLE doesn't exist.\n\n" \ "To fix this issue, create a template for the example." def initialize(example) super(MESSAGE.gsub("EXAMPLE", example)) end end class DuplicateContentError < StandardError MESSAGE = "It looks like a block was provided after calling `with_content` on COMPONENT, " \ "which means that ViewComponent doesn't know which content to use.\n\n" \ "To fix this issue, use either `with_content` or a block." def initialize(klass_name) super(MESSAGE.gsub("COMPONENT", klass_name.to_s)) end end class EmptyOrInvalidInitializerError < StandardError MESSAGE = "The COMPONENT initializer is empty or invalid. " \ "It must accept the parameter `PARAMETER` to render it as a collection.\n\n" \ "To fix this issue, update the initializer to accept `PARAMETER`.\n\n" \ "See [the collections docs](https://viewcomponent.org/guide/collections.html) for more information on rendering collections." def initialize(klass_name, parameter) super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("PARAMETER", parameter.to_s)) end end class MissingCollectionArgumentError < StandardError MESSAGE = "The initializer for COMPONENT doesn't accept the parameter `PARAMETER`, " \ "which is required to render it as a collection.\n\n" \ "To fix this issue, update the initializer to accept `PARAMETER`.\n\n" \ "See [the collections docs](https://viewcomponent.org/guide/collections.html) for more information on rendering collections." def initialize(klass_name, parameter) super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("PARAMETER", parameter.to_s)) end end class ReservedParameterError < StandardError MESSAGE = "COMPONENT initializer can't accept the parameter `PARAMETER`, as it will override a " \ "public ViewComponent method. To fix this issue, rename the parameter." def initialize(klass_name, parameter) super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("PARAMETER", parameter.to_s)) end end class InvalidCollectionArgumentError < BaseError MESSAGE = "The value of the first argument passed to `with_collection` isn't a valid collection. " \ "Make sure it responds to `to_ary`." end class ContentSlotNameError < StandardError MESSAGE = "COMPONENT declares a slot named content, which is a reserved word in ViewComponent.\n\n" \ "Content passed to a ViewComponent as a block is captured and assigned to the `content` accessor without having to create an explicit slot.\n\n" \ "To fix this issue, either use the `content` accessor directly or choose a different slot name." def initialize(klass_name) super(MESSAGE.gsub("COMPONENT", klass_name.to_s)) end end class InvalidSlotDefinitionError < BaseError MESSAGE = "Invalid slot definition. Please pass a class, " \ "string, or callable (that is proc, lambda, etc)" end class SlotPredicateNameError < StandardError MESSAGE = "COMPONENT declares a slot named SLOT_NAME, which ends with a question mark.\n\n" \ "This isn't allowed because the ViewComponent framework already provides predicate " \ "methods ending in `?`.\n\n" \ "To fix this issue, choose a different name." def initialize(klass_name, slot_name) super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("SLOT_NAME", slot_name.to_s)) end end class RedefinedSlotError < StandardError MESSAGE = "COMPONENT declares the SLOT_NAME slot multiple times.\n\n" \ "To fix this issue, choose a different slot name." def initialize(klass_name, slot_name) super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("SLOT_NAME", slot_name.to_s)) end end class ReservedSingularSlotNameError < StandardError MESSAGE = "COMPONENT declares a slot named SLOT_NAME, which is a reserved word in the ViewComponent framework.\n\n" \ "To fix this issue, choose a different name." def initialize(klass_name, slot_name) super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("SLOT_NAME", slot_name.to_s)) end end class ReservedPluralSlotNameError < StandardError MESSAGE = "COMPONENT declares a slot named SLOT_NAME, which is a reserved word in the ViewComponent framework.\n\n" \ "To fix this issue, choose a different name." def initialize(klass_name, slot_name) super(MESSAGE.gsub("COMPONENT", klass_name.to_s).gsub("SLOT_NAME", slot_name.to_s)) end end class ContentAlreadySetForPolymorphicSlotError < StandardError MESSAGE = "Content for slot SLOT_NAME has already been provided." def initialize(slot_name) super(MESSAGE.gsub("SLOT_NAME", slot_name.to_s)) end end class NilWithContentError < BaseError MESSAGE = "No content provided to `#with_content` for #{self}.\n\n" \ "To fix this issue, pass a value." end class TranslateCalledBeforeRenderError < BaseError MESSAGE = "`#translate` can't be used during initialization as it depends " \ "on the view context that only exists once a ViewComponent is passed to " \ "the Rails render pipeline.\n\n" \ "It's sometimes possible to fix this issue by moving code dependent on " \ "`#translate` to a [`#before_render` method](https://viewcomponent.org/api.html#before_render--void)." end class HelpersCalledBeforeRenderError < BaseError MESSAGE = "`#helpers` can't be used during initialization as it depends " \ "on the view context that only exists once a ViewComponent is passed to " \ "the Rails render pipeline.\n\n" \ "It's sometimes possible to fix this issue by moving code dependent on " \ "`#helpers` to a [`#before_render` method](https://viewcomponent.org/api.html#before_render--void)." end class ControllerCalledBeforeRenderError < BaseError MESSAGE = "`#controller` can't be used during initialization, as it depends " \ "on the view context that only exists once a ViewComponent is passed to " \ "the Rails render pipeline.\n\n" \ "It's sometimes possible to fix this issue by moving code dependent on " \ "`#controller` to a [`#before_render` method](https://viewcomponent.org/api.html#before_render--void)." end class NoMatchingTemplatesForPreviewError < StandardError MESSAGE = "Found 0 matches for templates for TEMPLATE_IDENTIFIER." def initialize(template_identifier) super(MESSAGE.gsub("TEMPLATE_IDENTIFIER", template_identifier)) end end class MultipleMatchingTemplatesForPreviewError < StandardError MESSAGE = "Found multiple templates for TEMPLATE_IDENTIFIER." def initialize(template_identifier) super(MESSAGE.gsub("TEMPLATE_IDENTIFIER", template_identifier)) end end class SystemTestControllerOnlyAllowedInTestError < BaseError MESSAGE = "ViewComponent SystemTest controller must only be called in a test environment for security reasons." end class SystemTestControllerNefariousPathError < BaseError MESSAGE = "ViewComponent SystemTest controller attempted to load a file outside of the expected directory." end end