1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
|
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, templates = nil)
message = errors.join("\n")
super(message)
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 MissingTemplateError < StandardError
MESSAGE =
"No templates for COMPONENT match the request DETAIL.\n\n" \
"To fix this issue, provide a suitable template."
def initialize(component, request_detail)
detail = {
locale: request_detail.locale,
formats: request_detail.formats,
variants: request_detail.variants,
handlers: request_detail.handlers
}
super(MESSAGE.gsub("COMPONENT", component).gsub("DETAIL", detail.inspect))
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 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 InvalidSlotNameError < StandardError
end
class SlotPredicateNameError < InvalidSlotNameError
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 < InvalidSlotNameError
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 < InvalidSlotNameError
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 UncountableSlotNameError < InvalidSlotNameError
MESSAGE =
"COMPONENT declares a slot named SLOT_NAME, which is an uncountable word\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 before rendering 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 before rendering 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 before rendering, 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 SystemTestControllerNefariousPathError < BaseError
MESSAGE = "ViewComponent SystemTest controller attempted to load a file outside of the expected directory."
end
class AlreadyDefinedPolymorphicSlotSetterError < StandardError
MESSAGE =
"A method called 'SETTER_METHOD_NAME' already exists and would be overwritten by the 'SETTER_NAME' polymorphic " \
"slot setter.\n\nPlease choose a different setter name."
def initialize(setter_method_name, setter_name)
super(MESSAGE.gsub("SETTER_METHOD_NAME", setter_method_name.to_s).gsub("SETTER_NAME", setter_name.to_s))
end
end
end
|