triannon 0.7.1 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c06b2318bdc1a94d4146dc592bb7b4fcb342f15b
4
- data.tar.gz: 0ff0a8f5ead3e6f81b43581608de22f9024db270
3
+ metadata.gz: 2548790e908598e117e457e7e2d051e30a9f40e4
4
+ data.tar.gz: 92b887940f9dcc100cb1c6aeca47f44b1aa2f641
5
5
  SHA512:
6
- metadata.gz: 40452508dfc9e3a9a131ab837b4e1042d38fa2fdcb11d4dd6066e492f0a287d832a8858c2985866d92e8d48302110d250794a602bcd88a4fad434cc633e90df5
7
- data.tar.gz: 91b264efab1f7449eed84376f5b8019f2a734ad43037377908e0d6c269f90529a8c2a2f4125d3b2bb03a92972892d3a79526d1403ba3379d497456a8815457d6
6
+ metadata.gz: 1fefd1bc5ea2b5e8d69d2c48c4cd7d8422ba861815f6ad79b89a44abf05bd2d81588e2226f41f2c8ab823741e56188023da18b4429ba7eb520dc1b46a7f42ba6
7
+ data.tar.gz: 87e9f142299da474e9f4ea8ba7405efa549429e883d2d0350986814571dd4d73bee2ad9cc993d2061b55949530cf8e8c6c48188725172a31087e1800bcb35de5
data/Rakefile CHANGED
@@ -11,13 +11,9 @@ require 'jettywrapper'
11
11
 
12
12
  require 'engine_cart/rake_task'
13
13
  desc 'run the triannon specs'
14
- task :ci => ['engine_cart:generate', 'jetty:clean'] do
15
- # run the tests
14
+ task :ci => 'engine_cart:generate' do
16
15
  RAILS_ENV = 'test'
17
- jetty_params = Jettywrapper.load_config.merge({:jetty_home => File.expand_path(File.dirname(__FILE__) + '/jetty')})
18
- Jettywrapper.wrap(jetty_params) do
19
- Rake::Task['spec'].invoke
20
- end
16
+ Rake::Task['spec'].invoke
21
17
  end
22
18
 
23
19
  namespace :triannon do
@@ -4,9 +4,11 @@ module Triannon
4
4
  class AnnotationsController < ApplicationController
5
5
  include RdfResponseFormats
6
6
 
7
+ rescue_from Triannon::LDPStorageError, with: :ldp_storage_error
8
+ rescue_from Triannon::ExternalReferenceError, with: :ext_ref_error
9
+ rescue_from Triannon::SearchError, with: :search_error
7
10
  before_action :default_format_jsonld, only: [:show]
8
11
  before_action :set_annotation, only: [:show, :update, :destroy]
9
- rescue_from Triannon::ExternalReferenceError, with: :ext_ref_error
10
12
 
11
13
  # GET /annotations
12
14
  def index
@@ -133,9 +135,21 @@ private
133
135
  @annotation = Annotation.find(params[:id])
134
136
  end
135
137
 
136
- # handle Triannon::ExternalReferenceError
137
- def ext_ref_error(exception)
138
- render plain: exception.message, status: 403
138
+ # render Triannon::ExternalReferenceError
139
+ def ext_ref_error(err)
140
+ render plain: err.message, status: 403
141
+ end
142
+
143
+ # render Triannon::LDPStorage error
144
+ def ldp_storage_error(err)
145
+ render :body => "<h2>#{err.message}</h2>" + err.ldp_resp_body, status: err.ldp_resp_status, content_type: "text/html"
146
+ end
147
+
148
+ # render Triannon::SearchError
149
+ def search_error(err)
150
+ render :body => "<h2>#{err.message}</h2>" + (err.search_resp_body ? err.search_resp_body : ""),
151
+ status: err.search_resp_status ? err.search_resp_status : 400,
152
+ content_type: "text/html"
139
153
  end
140
154
 
141
155
  # render json_ld respecting requested context
@@ -5,6 +5,7 @@ module Triannon
5
5
  include RdfResponseFormats
6
6
 
7
7
  before_action :default_format_jsonld, only: [:find]
8
+ rescue_from Triannon::SearchError, with: :search_error
8
9
 
9
10
  def find
10
11
  anno_graphs_array = solr_searcher.find(params)
@@ -40,6 +41,14 @@ module Triannon
40
41
  @ss ||= Triannon::SolrSearcher.new
41
42
  end
42
43
 
44
+ private
45
+
46
+ # render Triannon::SearchError
47
+ def search_error(err)
48
+ render :body => "<h2>#{err.message}</h2>" + (err.search_resp_body ? err.search_resp_body : ""),
49
+ status: err.search_resp_status ? err.search_resp_status : 400,
50
+ content_type: "text/html"
51
+ end
43
52
 
44
53
  end # SearchController
45
54
 
@@ -1,7 +1,7 @@
1
1
  module Triannon
2
2
  class Annotation
3
3
  include ActiveModel::Model
4
-
4
+
5
5
  define_model_callbacks :save, :destroy
6
6
  after_save :solr_save
7
7
  after_destroy :solr_delete
@@ -19,7 +19,7 @@ module Triannon
19
19
 
20
20
 
21
21
  # Class Methods ----------------------------------------------------------------
22
-
22
+
23
23
  def self.create(attrs = {})
24
24
  a = Triannon::Annotation.new attrs
25
25
  a.save
@@ -77,12 +77,12 @@ module Triannon
77
77
  @graph = Triannon::Graph.new g
78
78
  end
79
79
  end
80
-
80
+
81
81
  # @return json-ld representation of anno with OpenAnnotation context as a url
82
82
  def jsonld_oa
83
83
  graph.jsonld_oa
84
84
  end
85
-
85
+
86
86
  # @return json-ld representation of anno with IIIF context as a url
87
87
  def jsonld_iiif
88
88
  graph.jsonld_iiif
@@ -109,7 +109,7 @@ protected
109
109
  def solr_delete
110
110
  solr_writer.delete(id) if id
111
111
  end
112
-
112
+
113
113
  private
114
114
 
115
115
  # loads RDF::Graph from data attribute. If data is in json-ld or rdfxml, converts it to turtle.
@@ -130,7 +130,7 @@ private
130
130
  else # infer the content type from the content itself
131
131
  case data
132
132
  # \A and \Z and m are needed instead of ^$ due to \n in data
133
- when /\A\{.+\}\Z/m
133
+ when /\A\{.+\}\Z/m
134
134
  g = jsonld_to_graph
135
135
  when /\A<.+>\Z/m
136
136
  g = rdfxml_to_graph
@@ -143,7 +143,7 @@ private
143
143
  end
144
144
  g
145
145
  end
146
-
146
+
147
147
  # create and load an RDF::Graph object from turtle in data attrib
148
148
  # @return [RDF::Graph] populated RDF::Graph object, or nil
149
149
  def ttl_to_graph
@@ -37,7 +37,7 @@ module Triannon
37
37
 
38
38
  # load body objects into @ldp_annotation's (our Triannon::AnnotationLdp object) graph
39
39
  def load_bodies
40
- @ldp_annotation.body_uris.each { |body_uri|
40
+ @ldp_annotation.body_uris.each { |body_uri|
41
41
  body_obj_path = body_uri.to_s.split(@base_uri + '/').last
42
42
  load_object_into_annotation_graph(body_obj_path)
43
43
  }
@@ -45,12 +45,12 @@ module Triannon
45
45
 
46
46
  # load target objects into @ldp_annotation's (our Triannon::AnnotationLdp object) graph
47
47
  def load_targets
48
- @ldp_annotation.target_uris.each { |target_uri|
48
+ @ldp_annotation.target_uris.each { |target_uri|
49
49
  target_obj_path = target_uri.to_s.split(@base_uri + '/').last
50
50
  load_object_into_annotation_graph(target_obj_path)
51
51
  }
52
52
  end
53
-
53
+
54
54
  # @return [Array<Triannon::Annotation>] an array of Triannon::Annotation objects with just the id set. Enough info to build the index page
55
55
  def find_all
56
56
  root_ttl = get_ttl
@@ -83,13 +83,17 @@ module Triannon
83
83
  req.url "#{sub_path}" if sub_path
84
84
  req.headers['Accept'] = 'application/x-turtle'
85
85
  end
86
- resp.body
86
+ if resp.status.between?(400, 600)
87
+ raise Triannon::LDPStorageError.new("error getting #{sub_path} from LDP", resp.status, resp.body)
88
+ else
89
+ resp.body
90
+ end
87
91
  end
88
92
 
89
93
  # turns turtle serialization into Array of RDF::Statements, removing fedora-specific triples
90
94
  # (leaving LDP and OA triples)
91
95
  # @param [String] ttl a String containing RDF serialized as turtle
92
- # @return [Array<RDF::Statements>] the RDF statements represented in the ttl
96
+ # @return [Array<RDF::Statements>] the RDF statements represented in the ttl
93
97
  def statements_from_ttl_minus_fedora ttl
94
98
  # RDF::Turtle::Reader.new(ttl).statements.to_a
95
99
  g = RDF::Graph.new.from_ttl(ttl) if ttl
@@ -98,6 +102,8 @@ module Triannon
98
102
 
99
103
  def conn
100
104
  @c ||= Faraday.new @base_uri
105
+ @c.headers['Prefer'] = 'return=respresentation; omit="http://fedora.info/definitions/v4/repository#ServerManaged"'
106
+ @c
101
107
  end
102
108
 
103
109
  end
@@ -7,7 +7,7 @@ module Triannon
7
7
  # @param [Triannon::Annotation] anno a Triannon::Annotation object, from which we use the graph
8
8
  def self.create_anno(anno)
9
9
  if anno && anno.graph
10
- # TODO: special case if the Annotation object already has an id --
10
+ # TODO: special case if the Annotation object already has an id --
11
11
  # see https://github.com/sul-dlss/triannon/issues/84
12
12
  ldp_writer = Triannon::LdpWriter.new anno
13
13
  id = ldp_writer.create_base
@@ -39,11 +39,11 @@ module Triannon
39
39
  ldpw.delete_containers id
40
40
  end
41
41
  end
42
-
42
+
43
43
  class << self
44
44
  alias_method :delete_anno, :delete_container
45
45
  end
46
-
46
+
47
47
  # @param [Triannon::Annotation] anno a Triannon::Annotation object
48
48
  # @param [String] id the unique id for the LDP container for the passed annotation; defaults to nil
49
49
  def initialize(anno, id=nil)
@@ -59,14 +59,14 @@ module Triannon
59
59
  if @anno.graph.query([nil, RDF::Triannon.externalReference, nil]).count > 0
60
60
  raise Triannon::ExternalReferenceError, "Incoming annotations may not have http://triannon.stanford.edu/ns/externalReference as a predicate."
61
61
  end
62
-
62
+
63
63
  if @anno.graph.id_as_url && @anno.graph.id_as_url.size > 0
64
64
  raise Triannon::ExternalReferenceError, "Incoming new annotations may not have an existing id (yet)."
65
65
  end
66
66
 
67
- # TODO: special case if the Annotation object already has an id --
67
+ # TODO: special case if the Annotation object already has an id --
68
68
  # see https://github.com/sul-dlss/triannon/issues/84
69
-
69
+
70
70
  # we need to work with a copy of the graph so we don't change @anno.graph
71
71
  g = RDF::Graph.new
72
72
  @anno.graph.each { |s|
@@ -93,7 +93,7 @@ module Triannon
93
93
  def create_body_resources
94
94
  create_resources_in_container RDF::OpenAnnotation.hasBody
95
95
  end
96
-
96
+
97
97
  # create the target resources inside the (already created) target container
98
98
  def create_target_resources
99
99
  create_resources_in_container RDF::OpenAnnotation.hasTarget
@@ -108,11 +108,11 @@ module Triannon
108
108
  ldp_container_uris = [ldp_container_uris]
109
109
  end
110
110
  something_deleted = false
111
- ldp_container_uris.each { |uri|
111
+ ldp_container_uris.each { |uri|
112
112
  ldp_id = uri.to_s.split(@base_uri + '/').last
113
113
  resp = conn.delete { |req| req.url ldp_id }
114
114
  if resp.status != 204
115
- raise "Unable to delete LDP container: #{ldp_id}\nResponse Status: #{resp.status}\nResponse Body: #{resp.body}"
115
+ raise Triannon::LDPStorageError.new("Unable to delete LDP container #{ldp_id}", resp.status, resp.body)
116
116
  end
117
117
  something_deleted = true
118
118
  }
@@ -121,8 +121,8 @@ module Triannon
121
121
 
122
122
  protected
123
123
 
124
- # POSTS a ttl representation of a graph to a newly created LDP container in the LDP store
125
- # @param [String] ttl a turtle representation of RDF data to be put in the new LDP container
124
+ # POSTS a ttl representation of a graph to an existing LDP container in the LDP store
125
+ # @param [String] ttl a turtle representation of RDF data to be put in the LDP container
126
126
  # @param [String] parent_path the path portion of the url for the LDP parent container for this resource
127
127
  # if no path is supplied, then the resource will be created as a child of the root annotation;
128
128
  # expected paths would also be (anno_id)/t for a target resource (inside the target container of anno_id)
@@ -136,12 +136,12 @@ module Triannon
136
136
  req.body = ttl
137
137
  end
138
138
  if resp.status != 200 && resp.status != 201
139
- raise "Unable to create LDP resource in container #{parent_path}: Response Status: #{resp.status}\nResponse Body: #{resp.body}\nAnnotation sent: #{body}"
139
+ raise Triannon::LDPStorageError.new("Unable to create LDP resource in container #{parent_path}; RDF sent: #{ttl}", resp.status, resp.body)
140
140
  end
141
141
  new_url = resp.headers['Location'] ? resp.headers['Location'] : resp.headers['location']
142
142
  new_url.split('/').last if new_url
143
143
  end
144
-
144
+
145
145
  # Creates an empty LDP DirectContainer in LDP Storage that is a member of the base container and has the memberRelation per the oa_vocab_term
146
146
  # The id of the created containter will be (base container id)/b if hasBody or (base container id)/t if hasTarget
147
147
  # @param [RDF::Vocabulary::Term] oa_vocab_term RDF::OpenAnnotation.hasTarget or RDF::OpenAnnotation.hasBody
@@ -160,7 +160,7 @@ module Triannon
160
160
  req.body = g.to_ttl
161
161
  end
162
162
  if resp.status != 201
163
- raise "Unable to create #{oa_vocab_term.fragment.sub('has', '')} LDP container for anno: Response Status: #{resp.status}\nResponse Body: #{resp.body}"
163
+ raise Triannon::LDPStorageError.new("Unable to create #{oa_vocab_term.fragment.sub('has', '')} LDP container for anno; RDF sent: #{g.to_ttl}", resp.status, resp.body)
164
164
  end
165
165
  resp
166
166
  end
@@ -176,7 +176,7 @@ module Triannon
176
176
  if predicate_obj.is_a?(RDF::Node)
177
177
  # we need to use the null relative URI representation of blank nodes to write to LDP
178
178
  predicate_subject = RDF::URI.new
179
- else
179
+ else
180
180
  # it's already a URI, but we need to use the null relative URI representation so we can
181
181
  # write out as a Triannon:externalRef property with the URL, and any addl props too.
182
182
  if predicate_obj.to_str
@@ -185,7 +185,7 @@ module Triannon
185
185
  :predicate => RDF::Triannon.externalReference,
186
186
  :object => RDF::URI.new(predicate_obj.to_str)})
187
187
  addl_stmts = @anno.graph.query([predicate_obj, nil, nil])
188
- addl_stmts.each { |s|
188
+ addl_stmts.each { |s|
189
189
  graph_for_resource << RDF::Statement({:subject => predicate_subject,
190
190
  :predicate => s.predicate,
191
191
  :object => s.object})
@@ -194,13 +194,13 @@ module Triannon
194
194
  predicate_subject = predicate_obj
195
195
  end
196
196
  end
197
-
197
+
198
198
  # add statements with predicate_obj as the subject
199
199
  orig_hash_uri_objs = [] # the orig URI objects from [targetObject, OA.hasSource/.default/.item, (uri)] statements
200
200
  hash_uri_counter = 1
201
201
  Triannon::Graph.subject_statements(predicate_obj, @anno.graph).each { |s|
202
202
  if s.subject == predicate_obj
203
- # deal with any external URI references which may occur in:
203
+ # deal with any external URI references which may occur in:
204
204
  # OA.hasSource (from SpecificResource), OA.default or OA.item (from Choice, Composite, List)
205
205
  if s.object.is_a?(RDF::URI) && s.object.to_s
206
206
  # do we need to represent the URL as an externalReference with hash URI
@@ -218,7 +218,7 @@ module Triannon
218
218
  :predicate => s.predicate,
219
219
  :object => s.object})
220
220
  end
221
-
221
+
222
222
  if hash_uri_str
223
223
  # represent the object URL as an external ref
224
224
  new_hash_uri_obj = RDF::URI.new(hash_uri_str)
@@ -228,7 +228,7 @@ module Triannon
228
228
  graph_for_resource << RDF::Statement({:subject => predicate_subject,
229
229
  :predicate => s.predicate,
230
230
  :object => new_hash_uri_obj})
231
-
231
+
232
232
  # add externalReference triple to graph
233
233
  graph_for_resource << RDF::Statement({:subject => new_hash_uri_obj,
234
234
  :predicate => RDF::Triannon.externalReference,
@@ -251,15 +251,15 @@ module Triannon
251
251
  :predicate => s.predicate,
252
252
  :object => s.object})
253
253
  end
254
- else
255
- # s.subject != predicate_obj
254
+ else
255
+ # s.subject != predicate_obj
256
256
  graph_for_resource << s
257
257
  end
258
258
  }
259
259
  # make sure the graph we will write contains no extraneous statements about URIs
260
260
  # now represented as hash URIs
261
- orig_hash_uri_objs.each { |uri_node|
262
- Triannon::Graph.subject_statements(uri_node, graph_for_resource).each { |s|
261
+ orig_hash_uri_objs.each { |uri_node|
262
+ Triannon::Graph.subject_statements(uri_node, graph_for_resource).each { |s|
263
263
  graph_for_resource.delete(s)
264
264
  }
265
265
  }
@@ -274,6 +274,8 @@ module Triannon
274
274
 
275
275
  def conn
276
276
  @c ||= Faraday.new @base_uri
277
+ @c.headers['Prefer'] = 'return=respresentation; omit="http://fedora.info/definitions/v4/repository#ServerManaged"'
278
+ @c
277
279
  end
278
280
 
279
281
  end
@@ -14,7 +14,7 @@ module Triannon
14
14
  }
15
15
  result
16
16
  end
17
-
17
+
18
18
  # @note hardcoded Solr search service expectation in generated search params
19
19
  # @note hardcoded mapping of REST params for /search to Solr params
20
20
  #
@@ -114,6 +114,8 @@ module Triannon
114
114
  end
115
115
 
116
116
 
117
+ attr_accessor :rsolr_client
118
+
117
119
  def initialize
118
120
  @rsolr_client = RSolr.connect :url => Triannon.config[:solr_url]
119
121
  @logger = Rails.logger
@@ -145,6 +147,12 @@ module Triannon
145
147
  def search(solr_params = {})
146
148
  handler = Proc.new do |exception, attempt_cnt, total_delay|
147
149
  @logger.debug "#{exception.inspect} on Solr search attempt #{attempt_cnt} for #{solr_params.inspect}"
150
+ if exception.kind_of?(RSolr::Error::Http)
151
+ # Note there are extra shenanigans b/c RSolr hijacks the Solr error to return RSolr Error
152
+ raise Triannon::SearchError.new("error searching Solr with params #{solr_params.inspect}: #{exception.message}", exception.response[:status], exception.response[:body])
153
+ elsif exception.kind_of?(StandardError)
154
+ raise Triannon::SearchError.new("error searching Solr with params #{solr_params.inspect}: #{exception.message}")
155
+ end
148
156
  end
149
157
 
150
158
  response = nil
@@ -154,6 +162,7 @@ module Triannon
154
162
  :max_sleep_seconds => @max_sleep_seconds) do |attempt|
155
163
  @logger.debug "Solr search attempt #{attempt} for #{solr_params.inspect}"
156
164
  # use POST in case of long params
165
+ # RSolr throws RSolr::Error::Http for any Solr response without status 200 or 302
157
166
  response = @rsolr_client.post 'select', :params => solr_params
158
167
  @logger.info "Successfully searched Solr on attempt #{attempt}"
159
168
  end
@@ -47,6 +47,7 @@ module Triannon
47
47
  doc_hash
48
48
  end
49
49
 
50
+ attr_accessor :rsolr_client
50
51
 
51
52
  def initialize
52
53
  @rsolr_client = RSolr.connect :url => Triannon.config[:solr_url]
@@ -72,37 +73,51 @@ module Triannon
72
73
 
73
74
  handler = Proc.new do |exception, attempt_cnt, total_delay|
74
75
  @logger.debug "#{exception.inspect} on Solr add attempt #{attempt_cnt} for #{id}"
76
+ if exception.kind_of?(RSolr::Error::Http)
77
+ # Note there are extra shenanigans b/c RSolr hijacks the Solr error to return RSolr Error
78
+ raise Triannon::SearchError.new("error adding doc #{id} to Solr #{doc.inspect}; #{exception.message}", exception.response[:status], exception.response[:body])
79
+ elsif exception.kind_of?(StandardError)
80
+ raise Triannon::SearchError.new("error adding doc #{id} to Solr #{doc.inspect}; #{exception.message}")
81
+ end
75
82
  end
76
83
 
77
- with_retries(:handler => handler,
78
- :max_tries => @max_retries,
79
- :base_sleep_seconds => @base_sleep_seconds,
84
+ with_retries(:handler => handler,
85
+ :max_tries => @max_retries,
86
+ :base_sleep_seconds => @base_sleep_seconds,
80
87
  :max_sleep_seconds => @max_sleep_seconds) do |attempt|
81
88
  @logger.debug "Solr add attempt #{attempt} for #{id}"
82
89
  # add it and commit within 0.5 seconds
83
90
  @rsolr_client.add(doc, :add_attributes => {:commitWithin => 500})
91
+ # RSolr throws RSolr::Error::Http for any Solr response without status 200 or 302
84
92
  @logger.info "Successfully indexed #{id} to Solr on attempt #{attempt}"
85
93
  end
86
94
  end
87
-
95
+
88
96
  # Delete the document from Solr, retrying if an error occurs.
89
97
  # See https://github.com/ooyala/retries for info on with_retries.
90
98
  # @param [String] id the id of the Solr document to be deleted
91
99
  def delete(id)
92
100
  handler = Proc.new do |exception, attempt_cnt, total_delay|
93
101
  @logger.debug "#{exception.inspect} on Solr delete attempt #{attempt_cnt} for #{id}"
94
- end
102
+ if exception.kind_of?(RSolr::Error::Http)
103
+ # Note there are extra shenanigans b/c RSolr hijacks the Solr error to return RSolr Error
104
+ raise Triannon::SearchError.new("error deleting doc #{id} from Solr: #{exception.message}", exception.response[:status], exception.response[:body])
105
+ elsif exception.kind_of?(StandardError)
106
+ raise Triannon::SearchError.new("error deleting doc #{id} from Solr: #{exception.message}")
107
+ end
108
+ end
95
109
 
96
- with_retries(:handler => handler,
97
- :max_tries => @max_retries,
98
- :base_sleep_seconds => @base_sleep_seconds,
110
+ with_retries(:handler => handler,
111
+ :max_tries => @max_retries,
112
+ :base_sleep_seconds => @base_sleep_seconds,
99
113
  :max_sleep_seconds => @max_sleep_seconds) do |attempt|
100
114
  @logger.debug "Solr delete attempt #{attempt} for #{id}"
115
+ # RSolr throws RSolr::Error::Http for any Solr response without status 200 or 302
101
116
  @rsolr_client.delete_by_id(id)
102
117
  @rsolr_client.commit
103
118
  @logger.info "Successfully deleted #{id} from Solr"
104
- end
119
+ end
105
120
  end
106
-
121
+
107
122
  end
108
123
  end
@@ -2,8 +2,31 @@ module Triannon
2
2
  # generic Triannon error allowing rescue to catch all Triannon exceptions
3
3
  class Error < RuntimeError
4
4
  end
5
-
5
+
6
6
  class ExternalReferenceError < Triannon::Error
7
+ def initialize(message = nil)
8
+ super(message)
9
+ end
7
10
  end
8
-
11
+
12
+ # used to keep HTTP response info from LDP
13
+ class LDPStorageError < Triannon::Error
14
+ attr_accessor :ldp_resp_status, :ldp_resp_body
15
+ def initialize(message = nil, ldp_resp_status = nil, ldp_resp_body = nil)
16
+ super(message)
17
+ self.ldp_resp_status = ldp_resp_status if ldp_resp_status
18
+ self.ldp_resp_body = ldp_resp_body if ldp_resp_body
19
+ end
20
+ end
21
+
22
+ # used to keep HTTP response info from Solr
23
+ class SearchError < Triannon::Error
24
+ attr_accessor :search_resp_status, :search_resp_body
25
+ def initialize(message = nil, search_resp_status = nil, search_resp_body = nil)
26
+ super(message)
27
+ self.search_resp_status = search_resp_status if search_resp_status
28
+ self.search_resp_body = search_resp_body if search_resp_body
29
+ end
30
+ end
31
+
9
32
  end
@@ -1,3 +1,3 @@
1
1
  module Triannon
2
- VERSION = "0.7.1"
2
+ VERSION = "0.7.2"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: triannon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 0.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Beer
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-04-07 00:00:00.000000000 Z
13
+ date: 2015-04-14 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rails