triannon 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
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