Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have some kind of an outcome object to group all outcome-related information #163

Open
ramontayag opened this issue Nov 26, 2018 · 7 comments

Comments

@ramontayag
Copy link
Contributor

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 the success/failure, error_code, message, and metadata (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.

@adomokos
Copy link
Owner

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!

@ramontayag
Copy link
Contributor Author

ramontayag commented Nov 27, 2018

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

@adomokos
Copy link
Owner

Looks like a good start! Go for it!

@ramontayag
Copy link
Contributor Author

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.

@adomokos
Copy link
Owner

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!

@gee-forr
Copy link
Contributor

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?

@ramontayag
Copy link
Contributor Author

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants