Description
The after_error
hook (called error boundaries in React) is quite primitive.
But we can use it to build a more ruby like rescues
hook:
class MyComponent
...
rescues do |error, info|
... # do whatever here
end
end
Like ruby rescue
, the rescues
method can take a list of exception classes. If the error raised is an instance of one of the exception classes, the rescues block will catch the error, otherwise it will get passed down the stack to any components further up (down?) the tree.
Like ruby rescue
you can have several rescues
in a component each with different blocks, or you can share the block with multiple exception classes.
Like ruby rescue
if given no exception class rescues
will default to StandardError
Also rescues
will automatically create the necessary wrapper classes, so that you can rescue errors raised in the component you are defining. This is not possible with after_error
which can only catch errors raised in components mounted from within the component defining the boundary.
class App < HyperComponent
include Hyperstack::Router
SCOPES = %i[all active completed]
VALID_ROUTES = "/:scope(#{SCOPES.join('|')})"
class NoRouteMatched < StandardError
end
render(SECTION, class: 'todo-app') do
DIV { @flash_message }
if @error_message
DIV do
DIV { @error_message }
BUTTON { 'okay' }.on(:click) { mutate @error_message = nil }
end
else
Header()
Switch() do
Route(App::VALID_ROUTES) { |match| Index(scope: Todo.send(match.params[:scope])) }
Route('/', exact: true) { Redirect('/all') }
Route('*') { |match| raise NoRouteMatched, match.url }
end
Footer()
end
end
rescues NoRouteMatched do |err|
mutate @flash_message = "I did not recogonize #{err.message}", history.push('/all')
after(3) { mutate @flash_message = nil }
end
rescues do |err|
mutate @error_message = "Something went wrong! #{err}"
end
end