Forum: Ruby on Rails Is it ok to use struct as constants in initializer?

Posted by comopasta Gr (comopasta)
on 2012-11-29 10:47
I want to define simple global objects that contain a code and
description for custom errors. Is it a bad idea to use structs in an
initializer in the app?

api_error_constants.rb in /config/initializers

error_type = Struct.new(:code, :description)
BAD_JSON = error_type.new("001" , "Problem parsing JSON")
BAD_XML = error_type.new("002" , "Problem parsing XML")
...
...

Or is there a more appropriate/standard way?
Posted by Jordon Bedwell (Guest)
on 2012-11-29 11:11
(Received via mailing list)
On Thu, Nov 29, 2012 at 3:47 AM, comopasta Gr <lists@ruby-forum.com> 
wrote:
> error_type = Struct.new(:code, :description)
> BAD_JSON = error_type.new("001" , "Problem parsing JSON")
> BAD_XML = error_type.new("002" , "Problem parsing XML")

class MyClass
  class APIParseError < StandardError
    def initialize(code, lib)
      @code = code
      @lib = lib
    end

    def to_s
      "#{@code}: Problem parsing #{@lib}"
    end
  end
end

raise(MyClass::APIParseError.new("001", :XML))
#=> MyClass::MyError: 001: Problem parsing XML
Posted by Jordon Bedwell (Guest)
on 2012-11-29 11:16
(Received via mailing list)
On Thu, Nov 29, 2012 at 4:11 AM, Jordon Bedwell <envygeeks@gmail.com> 
wrote:
> raise(MyClass::APIParseError.new("001", :XML))
> #=> MyClass::MyError: 001: Problem parsing XML

This would actually display: "MyClass::APIParseError" I had a
misspelling since I didn't run it through an REPL to get the output I
just wrote it so of course typos can happen but it will show you the
right error class when you output it.
Posted by comopasta Gr (comopasta)
on 2012-11-29 11:54
Jordon Bedwell wrote in post #1087053:
> On Thu, Nov 29, 2012 at 3:47 AM, comopasta Gr <lists@ruby-forum.com>
> wrote:
>> error_type = Struct.new(:code, :description)
>> BAD_JSON = error_type.new("001" , "Problem parsing JSON")
>> BAD_XML = error_type.new("002" , "Problem parsing XML")
>
> class MyClass
>   class APIParseError < StandardError
>     def initialize(code, lib)
>       @code = code
>       @lib = lib
>     end
>
>     def to_s
>       "#{@code}: Problem parsing #{@lib}"
>     end
>   end
> end
>
> raise(MyClass::APIParseError.new("001", :XML))
> #=> MyClass::MyError: 001: Problem parsing XML

Thanks Jordon. I wanted to keep my question simple but maybe it needed
more details. Sorry I have to paste a bunch of code...

I need to respond with the api using json:

{
  "result": {"created":"0","failed":"0"},
  "errors":[
    {"error":{"message":"Problem parsing JSON","code":"001"}}
  ]
}

I use Rabl to generate the json I give back. Rabl works well with
openStruct. There can be several errors to be reported.

--------

The controller delegates to a module this and other validations on the
json.

Relevant code from the controller:

@result = OpenStruct.new
@errors = []

entries = ApiUtilitiesV1::validateJson(request.body.read)
if entries != false
  ..keep processing, might add elements to the @errors array
else
  err = ApiUtilitiesV1::getError(BAD_JSON)
  @errors << err
end

@result.created = "#{created_counter}"
@result.failed = "#{failed_counter}"
render 'create' -> renders Rabl template using @result and @errors

-------

In the module where I have the api utilities there is:

def self.validateJson(json_string)
  begin
    parsed_vals = JSON.parse(json_string)
    return parsed_vals["entries"]
  rescue JSON::ParserError
    return false
  end
end

def self.getError(error_constant)
  error = OpenStruct.new
  error.message = error_constant.message
  error.code = error_constant.code
  return error
end

--------

The idea is to share the error codes defined in the structs between the
controller and the module. And also have a single method that provides
me with the data that goes in for each different error.

So I'm not sure how can I incorporate your suggestion into the logic I 
have. Or maybe the logic I have is completely a bad idea...
Posted by comopasta Gr (comopasta)
on 2012-11-30 14:01
Ok, I would remove my previous post if I could but I can't access it 
anymore.

In any case. I have improved that code to a better version where I rely 
on raise and rescues to handle exceptions generated by the module. No 
more ugly if xxxx != false

Anyway my question was not about how to generate exceptions but about 
the fact of using a struc in my initializers.

I would delete the whole thread anyway...
Posted by Colin Law (Guest)
on 2012-11-30 14:16
(Received via mailing list)
On 30 November 2012 13:01, comopasta Gr <lists@ruby-forum.com> wrote:
> I would delete the whole thread anyway...
This is a mailing list not a forum (though you may be accessing via a
forum like interface).  Emails cannot be deleted by the sender.  Once
it is on my machine only I can delete it (I hope, otherwise I am in
trouble).

Colin
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.