Skip to content

Commit 558ecdd

Browse files
committed
Better error handling and more informative error messages.
1 parent faa4b56 commit 558ecdd

File tree

5 files changed

+147
-28
lines changed

5 files changed

+147
-28
lines changed

lib/seek/doi/parser.rb

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,44 @@
44
module Seek
55
module Doi
66
class Parser
7-
87
DOI_ENDPOINT = 'https://doi.org'.freeze
9-
def self.parse(doi)
10-
return if doi.blank?
118

9+
def self.parse(doi)
1210
agency = get_doi_ra(doi)
11+
1312
case agency
1413
when 'DataCite'
1514
Seek::Doi::Parsers::DataciteParser.new.parse(doi)
1615
when 'Crossref'
1716
Seek::Doi::Parsers::CrossrefParser.new.parse(doi)
1817
else
19-
Rails.logger.warn("Unsupported DOI registration agency: #{agency}")
20-
{}
18+
raise Seek::Doi::RANotSupported, "DOI registration agency '#{agency}' is not supported."
2119
end
20+
rescue OpenURI::HTTPError => e
21+
# Handle RA resolution issues
22+
raise Seek::Doi::FetchException, "Error resolving DOI #{doi}: #{e.message}"
23+
rescue Seek::Doi::BaseException
24+
raise # Re-raise already handled domain exceptions
2225
rescue StandardError => e
23-
Rails.logger.error("DOI parsing failed for #{doi}: #{e.message}")
24-
{}
26+
# Fallback for truly unexpected errors
27+
raise Seek::Doi::FetchException, "Unexpected error resolving DOI #{doi}: #{e.message}"
2528
end
2629

2730
private_class_method def self.get_doi_ra(doi)
28-
prefix = doi.split('/').first
29-
url = DOI_ENDPOINT+"/ra/#{prefix}"
30-
data = JSON.parse(URI.open(url).read)
31-
data.dig(0, 'RA') # => "DataCite", "Crossref", etc.
32-
rescue StandardError => e
33-
Rails.logger.warn("Could not determine RA for DOI #{doi}: #{e.message}")
34-
nil
31+
url = "#{DOI_ENDPOINT}/ra/#{doi}"
32+
response = URI.open(url).read
33+
data = JSON.parse(response)
34+
ra = data.dig(0, 'RA')
35+
status = data.dig(0, 'status')
36+
37+
case status
38+
when 'Invalid DOI'
39+
raise Seek::Doi::MalformedDOIException, "Invalid DOI format: #{doi}."
40+
when 'DOI does not exist'
41+
raise Seek::Doi::NotFoundException, "DOI does not exist: #{doi}."
42+
end
43+
raise Seek::Doi::NotFoundException, "No registration agency found for DOI #{doi}" if ra.blank?
44+
ra
3545
end
3646
end
3747
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
require 'test_helper'
2+
3+
class DoiParserExceptionTest < ActiveSupport::TestCase
4+
5+
test 'raises RANotSupported for mEDRA DOI' do
6+
VCR.use_cassette('doi/medra_ra') do
7+
doi = '10.19232/uv4pb.2018.2.00'
8+
assert_equal 'mEDRA', Seek::Doi::Parser.send(:get_doi_ra, doi)
9+
end
10+
end
11+
12+
# Test that a DOI registered under mEDRA raises the correct exception
13+
test 'raises RANotSupported for mEDRA DOI11' do
14+
VCR.use_cassette('doi/medra_ra') do
15+
doi = '10.19232/uv4pb.2018.2.00'
16+
error = assert_raises(Seek::Doi::RANotSupported) do
17+
Seek::Doi::Parser.parse(doi)
18+
end
19+
assert_equal "DOI registration agency 'mEDRA' is not supported.", error.message
20+
end
21+
end
22+
23+
24+
test 'raises NotFoundException for fake DOI' do
25+
VCR.use_cassette('doi/fake_doi') do
26+
doi = '10.19232/fake.2020.1.23'
27+
error = assert_raises(Seek::Doi::NotFoundException) do
28+
Seek::Doi::Parser.send(:get_doi_ra, doi)
29+
end
30+
assert_equal 'DOI does not exist: 10.19232/fake.2020.1.23.', error.message
31+
end
32+
end
33+
34+
test 'raises MalformedDOIException for invalid DOI' do
35+
VCR.use_cassette('doi/invalid_doi') do
36+
doi = 'hello_march'
37+
error = assert_raises(Seek::Doi::MalformedDOIException) do
38+
Seek::Doi::Parser.send(:get_doi_ra, doi)
39+
end
40+
assert_equal 'Invalid DOI format: hello_march.', error.message
41+
end
42+
end
43+
44+
end
45+
46+
47+
# resource not found
48+
#10.31234/osf.io/8s4xq
49+
50+
# phd thesis can not be resolved
51+
#10.5445/IR/1000055628

test/vcr_cassettes/doi/fake_doi.yml

Lines changed: 58 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/vcr_cassettes/doi/datacite_ra.yml renamed to test/vcr_cassettes/doi/invalid_doi.yml

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/vcr_cassettes/doi/crossref_ra.yml renamed to test/vcr_cassettes/doi/medra_ra.yml

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)