Open ramontayag opened 5 years ago
Yep, that makes sense. I would have one caveat: let's keep it simple for folks who want to use LS just for simple scenarios.
I've started using Haskell professionally a couple of months ago, and I really enjoy how the language forces me to think about the "what if things don't work" use cases early on. I feel LS should be going in this direction as well.
Please start with initial sketches, let's make sure it's headed in the right direction before you invest too much time in it.
Thanks!
Ok cool. Yes I plan to not change the current signature.
I'm thinking of the following (pseudo code):
class LightService::Context
delegate :success?, :failure?, :error_code, :message, to: :outcome
attr_accessor :outcome
def fail!(message, data)
self.outcome = Outcome.new({success: false, message: message}.merge!(data))
end
end
class LightService::Outcome
attr_accessor :success, :message, :error_code, :metadata
def initialize(success: true, message: nil, error_code: nil, **metadata)
self.success = success
self.message = message
self.error_code = error_code
self.metadata = metadata
end
def success?
!!self.success
end
def failure?
!success?
end
end
Looks like a good start! Go for it!
Just an update. We've started using this in our app first, and just monkey-patching LS to behave the way intended. Soon, we should be able to make a pull request for this.
Yeah, that's how we added most of the functionality as well. First monkey-patch and see if it sticks. When it did, that got in as a PR. Thanks for the update!
Hey there, just chiming in, as I realised, it would be great if LS could tell me on which action in an organiser was the action that failed. This would be some super handy data when needing to debug. This seems like a perfect bit of data that should live in metadata. Something like:
my_org = MyOrganiser.call(foo: :bar)
my_org.success? # => false
my_org.outcome.metadata.failing_action # => MyBrokenAction
@ramontayag - is there any chance you will be releasing your changes soon, as an addon to the LS gem or a PR to the gem itself?
Yeah sure, pretty much anything can be thrown in there. We put it in an app but haven't extracted it yet. I will look for time to do so!
We use LightService as intended: to do pretty complex processes. Many of the actions may fail, and we would like to return more information to the thing that executed the organizer (like a Rails controller), besides the message and error code.
Take Stripe's "outcome" as an example (thanks @ace-subido). To implement this with LS, we'd need to flood the contexts with more information. If there existed an
outcome
object that would hold thesuccess
/failure
,error_code
,message
, andmetadata
(reason
,risk_level
would live here), the controller could expose this as they wish to the API user.What do you think of this? Can flesh it out more if it looks interesting.