{"id":1499,"date":"2025-03-24T08:50:35","date_gmt":"2025-03-23T23:50:35","guid":{"rendered":"https:\/\/dexall.co.jp\/articles\/?p=1499"},"modified":"2025-03-24T08:50:35","modified_gmt":"2025-03-23T23:50:35","slug":"%e3%80%90%e4%bf%9d%e5%ad%98%e7%89%88%e3%80%91ruby%e3%81%aeraise%e3%82%92%e5%ae%8c%e5%85%a8%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%81%e5%ae%9f%e8%b7%b5%e7%9a%84%e3%81%aa7%e3%81%a4%e3%81%ae%e4%bd%bf","status":"publish","type":"post","link":"https:\/\/dexall.co.jp\/articles\/?p=1499","title":{"rendered":"\u3010\u4fdd\u5b58\u7248\u3011Ruby\u306eRaise\u3092\u5b8c\u5168\u30de\u30b9\u30bf\u30fc\uff01\u5b9f\u8df5\u7684\u306a7\u3064\u306e\u4f7f\u3044\u65b9\u3068\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9"},"content":{"rendered":"\n<div class=\"toc\"><br \/>\n<b>Warning<\/b>:  Undefined array key \"is_admin\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>116<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_category_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>121<\/b><br \/>\n<br \/>\n<b>Warning<\/b>:  Undefined array key \"is_top\" in <b>\/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/sango-theme\/library\/gutenberg\/dist\/classes\/Toc.php<\/b> on line <b>128<\/b><br \/>\n    <div id=\"toc_container\" class=\"sgb-toc--bullets js-smooth-scroll\" data-dialog-title=\"\u76ee\u6b21\">\n      <p class=\"toc_title\">\u76ee\u6b21 <\/p>\n      <ul class=\"toc_list\">  <li class=\"first\">    <a href=\"#i-0\">Ruby\u306eraise\u3068\u306f\uff1f\u57fa\u790e\u304b\u3089\u7406\u89e3\u3059\u308b\u4f8b\u5916\u51e6\u7406<\/a>  <\/li>  <li>    <a href=\"#i-1\">raise\u30e1\u30bd\u30c3\u30c9\u306e\u57fa\u672c\u7684\u306a\u69cb\u6587\u3068\u5f79\u5272<\/a>  <\/li>  <li>    <a href=\"#i-2\">Ruby\u306e\u4f8b\u5916\u30af\u30e9\u30b9\u968e\u5c64\u306b\u3064\u3044\u3066<\/a>    <ul class=\"menu_level_1\">      <li class=\"first last\">        <a href=\"#i-3\">\u4f8b\u5916\u51e6\u7406\u306e\u57fa\u672c\u7684\u306a\u6d41\u308c<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-4\">raise\u306e\u5b9f\u8df5\u7684\u306a\u4f7f\u3044\u65b97\u9078<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-5\">1. \u30ab\u30b9\u30bf\u30e0\u4f8b\u5916\u30af\u30e9\u30b9\u306e\u5b9a\u7fa9\u3068\u6d3b\u7528\u65b9\u6cd5<\/a>      <\/li>      <li>        <a href=\"#i-6\">2. \u6761\u4ef6\u4ed8\u304d\u4e0a\u6607\u306b\u3088\u308b\u5165\u529b\u5024\u306e\u691c\u8a3c<\/a>      <\/li>      <li>        <a href=\"#i-7\">3. \u9632\u5fa1\u7684\u306a\u4f8b\u5916\u51e6\u7406\u306e\u5b9f\u88c5\u30c6\u30af\u30cb\u30c3\u30af<\/a>      <\/li>      <li>        <a href=\"#i-8\">4. \u30e1\u30c3\u30bb\u30fc\u30b8\u3068\u30d0\u30c3\u30af\u30c8\u30ec\u30fc\u30b9\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528<\/a>      <\/li>      <li>        <a href=\"#i-9\">5. \u4f8b\u5916\u51e6\u7406\u3092\u4f7f\u3063\u305f\u30ac\u30fc\u30c9\u7bc0\u30d1\u30bf\u30fc\u30f3<\/a>      <\/li>      <li>        <a href=\"#i-10\">6. \u5916\u90e8\u30e9\u30a4\u30d6\u30e9\u30ea\u3068\u306e\u9023\u643a\u6642\u306e\u4f8b\u5916\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-11\">7. \u30c6\u30b9\u30c8\u99c6\u52d5\u958b\u767a\u306b\u304a\u3051\u308braise\u306e\u6d3b\u7528<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-12\">\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-13\">\u6b63\u3057\u3044\u7c92\u5ea6\u3067\u306e\u4f8b\u5916\u8a2d\u8a08\u306e\u91cd\u8981\u6027<\/a>      <\/li>      <li>        <a href=\"#i-14\">rescue\/ensure\/else\u30d6\u30ed\u30c3\u30af\u306e\u5229\u7528<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-15\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3057\u305f\u30a8\u30e9\u30fc\u51e6\u7406\u306e\u5b9f\u88c5<\/a>      <\/li>    <\/ul>  <\/li>  <li>    <a href=\"#i-16\">\u3088\u304f\u3042\u308b\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\u3068\u6539\u5584\u65b9\u6cd5<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-17\">\u907f\u3051\u308b\u3079\u304d\u4f8b\u5916\u51e6\u7406\u306e\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-18\">\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u306b\u3088\u308b\u6539\u5584\u4f8b\u306e\u7d39\u4ecb<\/a>      <\/li>    <\/ul>  <\/li>  <li class=\"last\">    <a href=\"#i-19\">\u5b9f\u8df5\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u5225\u5b9f\u88c5\u4f8b<\/a>    <ul class=\"menu_level_1\">      <li class=\"first\">        <a href=\"#i-20\">WebAPI \u306e\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u5b9f\u88c5<\/a>      <\/li>      <li>        <a href=\"#i-21\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 \u30aa\u30da\u30ec\u30fc\u30b7\u30e7\u30f3\u6642\u306e\u4f8b\u5916\u51e6\u7406<\/a>      <\/li>      <li class=\"last\">        <a href=\"#i-22\">\u975e\u540c\u671f\u51e6\u7406\u306b\u304a\u3051\u308b\u30a8\u30e9\u30fc\u51e6\u7406<\/a>      <\/li>    <\/ul>  <\/li><\/ul>\n      <a href=\"#\" class=\"sgb-toc-button js-toc-button\" rel=\"nofollow\" data-open-dialog=\"true\"><i class=\"fa fa-list\"><\/i><span class=\"sgb-toc-button__text\">\u76ee\u6b21\u3078<\/span><\/a>\n    <\/div><\/div><h2 class=\"wp-block-heading\" id=\"i-0\">Ruby\u306eraise\u3068\u306f\uff1f\u57fa\u790e\u304b\u3089\u7406\u89e3\u3059\u308b\u4f8b\u5916\u51e6\u7406<\/h2>\n\n\n\n<p>\u30d7\u30ed\u30b0\u30e9\u30e0\u306e\u5b9f\u884c\u4e2d\u306b\u4e88\u671f\u3057\u306a\u3044\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3059\u308b\u3053\u3068\u306f\u907f\u3051\u3089\u308c\u307e\u305b\u3093\u3002Ruby\u3067\u306f\u3001\u3053\u306e\u3088\u3046\u306a\u7570\u5e38\u306a\u72b6\u6cc1\u3092\u9069\u5207\u306b\u51e6\u7406\u3059\u308b\u305f\u3081\u306b\u300c\u4f8b\u5916\u51e6\u7406\u300d\u3068\u3044\u3046\u6a5f\u80fd\u304c\u63d0\u4f9b\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u305d\u306e\u4e2d\u5fc3\u3068\u306a\u308b\u306e\u304c<code>raise<\/code>\u30e1\u30bd\u30c3\u30c9\u3067\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-1\">raise\u30e1\u30bd\u30c3\u30c9\u306e\u57fa\u672c\u7684\u306a\u69cb\u6587\u3068\u5f79\u5272<\/h2>\n\n\n\n<p><code>raise<\/code>\u30e1\u30bd\u30c3\u30c9\u306f\u3001\u30d7\u30ed\u30b0\u30e9\u30e0\u306e\u5b9f\u884c\u4e2d\u306b\u610f\u56f3\u7684\u306b\u4f8b\u5916\u3092\u767a\u751f\u3055\u305b\u308b\u305f\u3081\u306e\u30e1\u30bd\u30c3\u30c9\u3067\u3059\u3002\u57fa\u672c\u7684\u306a\u69cb\u6587\u306f\u4ee5\u4e0b\u306e\u901a\u308a\u3067\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u57fa\u672c\u7684\u306a\u4f7f\u3044\u65b9\nraise                    # RuntimeError\u3092\u767a\u751f\u3055\u305b\u308b\nraise \"\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\"   # \u30e1\u30c3\u30bb\u30fc\u30b8\u4ed8\u304d\u306eRuntimeError\u3092\u767a\u751f\u3055\u305b\u308b\nraise ArgumentError      # \u7279\u5b9a\u306e\u4f8b\u5916\u30af\u30e9\u30b9\u3092\u767a\u751f\u3055\u305b\u308b\nraise ArgumentError, \"\u4e0d\u6b63\u306a\u5f15\u6570\u3067\u3059\" # \u30e1\u30c3\u30bb\u30fc\u30b8\u4ed8\u304d\u306e\u7279\u5b9a\u4f8b\u5916\u3092\u767a\u751f\u3055\u305b\u308b<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-2\">Ruby\u306e\u4f8b\u5916\u30af\u30e9\u30b9\u968e\u5c64\u306b\u3064\u3044\u3066<\/h2>\n\n\n\n<p>Ruby\u306e\u4f8b\u5916\u30af\u30e9\u30b9\u306f\u968e\u5c64\u69cb\u9020\u306b\u306a\u3063\u3066\u3044\u307e\u3059\uff1a<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Exception\n\u251c\u2500\u2500 NoMemoryError\n\u251c\u2500\u2500 ScriptError\n\u2502   \u251c\u2500\u2500 LoadError\n\u2502   \u251c\u2500\u2500 NotImplementedError\n\u2502   \u2514\u2500\u2500 SyntaxError\n\u2514\u2500\u2500 StandardError      # \u6700\u3082\u4e00\u822c\u7684\u306b\u4f7f\u7528\u3055\u308c\u308b\u4f8b\u5916\u306e\u57fa\u5e95\u30af\u30e9\u30b9\n    \u251c\u2500\u2500 ArgumentError  # \u30e1\u30bd\u30c3\u30c9\u306e\u5f15\u6570\u304c\u4e0d\u6b63\u306a\u5834\u5408\n    \u251c\u2500\u2500 NameError     # \u672a\u5b9a\u7fa9\u306e\u5909\u6570\u3084\u30e1\u30bd\u30c3\u30c9\u3092\u53c2\u7167\u3057\u305f\u5834\u5408\n    \u2502   \u2514\u2500\u2500 NoMethodError\n    \u251c\u2500\u2500 RuntimeError  # \u30c7\u30d5\u30a9\u30eb\u30c8\u306e\u4f8b\u5916\u30af\u30e9\u30b9\n    \u251c\u2500\u2500 SecurityError\n    \u2514\u2500\u2500 TypeError     # \u671f\u5f85\u3055\u308c\u308b\u578b\u3068\u7570\u306a\u308b\u5834\u5408\n\n# \u4f8b\u5916\u30af\u30e9\u30b9\u306e\u5b9f\u969b\u306e\u4f7f\u7528\u4f8b\ndef divide(a, b)\n  raise TypeError, \"\u6570\u5024\u3092\u5165\u529b\u3057\u3066\u304f\u3060\u3055\u3044\" unless a.is_a?(Numeric) &amp;&amp; b.is_a?(Numeric)\n  raise ArgumentError, \"0\u3067\u306e\u9664\u7b97\u306f\u3067\u304d\u307e\u305b\u3093\" if b.zero?\n  a \/ b\nend\n\n# \u4f7f\u7528\u4f8b\u3068\u7d50\u679c\nbegin\n  result = divide(10, 0)\nrescue ArgumentError =&gt; e\n  puts \"\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: #{e.message}\"\nrescue TypeError =&gt; e\n  puts \"\u578b\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f: #{e.message}\"\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-3\">\u4f8b\u5916\u51e6\u7406\u306e\u57fa\u672c\u7684\u306a\u6d41\u308c<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u4f8b\u5916\u306e\u767a\u751f<\/strong>: <code>raise<\/code>\u30e1\u30bd\u30c3\u30c9\u306b\u3088\u308a\u4f8b\u5916\u304c\u767a\u751f\u3057\u307e\u3059<\/li>\n\n\n\n<li><strong>\u4f8b\u5916\u306e\u4f1d\u64ad<\/strong>: \u4f8b\u5916\u306f\u547c\u3073\u51fa\u3057\u968e\u5c64\u3092\u4e0a\u3063\u3066\u3044\u304d\u307e\u3059<\/li>\n\n\n\n<li><strong>\u4f8b\u5916\u306e\u6355\u6349<\/strong>: <code>rescue<\/code>\u7bc0\u3067\u4f8b\u5916\u3092\u6355\u6349\u3057\u307e\u3059<\/li>\n\n\n\n<li><strong>\u5f8c\u51e6\u7406\u306e\u5b9f\u884c<\/strong>: <code>ensure<\/code>\u7bc0\u3067\u5fc5\u8981\u306a\u5f8c\u51e6\u7406\u3092\u884c\u3044\u307e\u3059<\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u57fa\u672c\u7684\u306a\u4f8b\u5916\u51e6\u7406\u306e\u69cb\u9020\nbegin\n  # \u4f8b\u5916\u304c\u767a\u751f\u3059\u308b\u53ef\u80fd\u6027\u306e\u3042\u308b\u30b3\u30fc\u30c9\n  raise \"\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\"\nrescue StandardError =&gt; e\n  # \u4f8b\u5916\u3092\u6355\u6349\u3057\u3066\u51e6\u7406\u3059\u308b\u30b3\u30fc\u30c9\n  puts \"\u30a8\u30e9\u30fc: #{e.message}\"\nensure\n  # \u5fc5\u305a\u5b9f\u884c\u3055\u308c\u308b\u5f8c\u51e6\u7406\u306e\u30b3\u30fc\u30c9\n  puts \"\u51e6\u7406\u3092\u7d42\u4e86\u3057\u307e\u3059\"\nend<\/pre>\n\n\n\n<p>\u3053\u306e\u57fa\u672c\u7684\u306a\u7406\u89e3\u3092\u5143\u306b\u3001\u3088\u308a\u5b9f\u8df5\u7684\u306a\u4f7f\u3044\u65b9\u3084\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3092\u5b66\u3093\u3067\u3044\u304f\u3053\u3068\u3067\u3001\u5805\u7262\u306a\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u958b\u767a\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-4\">raise\u306e\u5b9f\u8df5\u7684\u306a\u4f7f\u3044\u65b97\u9078<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-5\">1. \u30ab\u30b9\u30bf\u30e0\u4f8b\u5916\u30af\u30e9\u30b9\u306e\u5b9a\u7fa9\u3068\u6d3b\u7528\u65b9\u6cd5<\/h3>\n\n\n\n<p>\u72ec\u81ea\u306e\u4f8b\u5916\u30af\u30e9\u30b9\u3092\u5b9a\u7fa9\u3059\u308b\u3053\u3068\u3067\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u56fa\u6709\u306e\u30a8\u30e9\u30fc\u3092\u9069\u5207\u306b\u8868\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30ab\u30b9\u30bf\u30e0\u4f8b\u5916\u30af\u30e9\u30b9\u306e\u5b9a\u7fa9\nclass ValidationError &lt; StandardError\n  attr_reader :field, :value\n\n  def initialize(message, field: nil, value: nil)\n    @field = field\n    @value = value\n    super(message)\n  end\nend\n\n# \u4f7f\u7528\u4f8b\nclass User\n  def save_profile(params)\n    if params[:age] &amp;&amp; params[:age] &lt; 0\n      raise ValidationError.new(\"\u5e74\u9f62\u306f0\u4ee5\u4e0a\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\",\n                              field: :age,\n                              value: params[:age])\n    end\n    # \u4fdd\u5b58\u51e6\u7406\n  end\nend\n\n# \u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\nbegin\n  user.save_profile(age: -1)\nrescue ValidationError =&gt; e\n  puts \"\u691c\u8a3c\u30a8\u30e9\u30fc: #{e.message}\"\n  puts \"\u554f\u984c\u306e\u30d5\u30a3\u30fc\u30eb\u30c9: #{e.field}\"\n  puts \"\u5165\u529b\u5024: #{e.value}\"\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-6\">2. \u6761\u4ef6\u4ed8\u304d\u4e0a\u6607\u306b\u3088\u308b\u5165\u529b\u5024\u306e\u691c\u8a3c<\/h3>\n\n\n\n<p>\u30e1\u30bd\u30c3\u30c9\u306e\u5165\u529b\u5024\u3092\u691c\u8a3c\u3059\u308b\u969b\u3001\u6761\u4ef6\u306b\u5fdc\u3058\u3066\u9069\u5207\u306a\u4f8b\u5916\u3092\u767a\u751f\u3055\u305b\u308b\u3053\u3068\u3067\u3001\u65e9\u671f\u306b\u30a8\u30e9\u30fc\u3092\u691c\u51fa\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class PaymentProcessor\n  def process_payment(amount, currency)\n    # \u91d1\u984d\u306e\u691c\u8a3c\n    raise ArgumentError, \"\u91d1\u984d\u306f\u6b63\u306e\u6570\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\" unless amount.positive?\n\n    # \u901a\u8ca8\u30b3\u30fc\u30c9\u306e\u691c\u8a3c\n    valid_currencies = [\"JPY\", \"USD\", \"EUR\"]\n    raise ArgumentError, \"\u4e0d\u6b63\u306a\u901a\u8ca8\u30b3\u30fc\u30c9\u3067\u3059: #{currency}\" unless valid_currencies.include?(currency)\n\n    # \u652f\u6255\u3044\u51e6\u7406\u306e\u5b9f\u884c\n    perform_payment(amount, currency)\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-7\">3. \u9632\u5fa1\u7684\u306a\u4f8b\u5916\u51e6\u7406\u306e\u5b9f\u88c5\u30c6\u30af\u30cb\u30c3\u30af<\/h3>\n\n\n\n<p>\u5916\u90e8\u30b5\u30fc\u30d3\u30b9\u3068\u306e\u9023\u643a\u6642\u306a\u3069\u3001\u4e88\u671f\u305b\u306c\u30a8\u30e9\u30fc\u306b\u5bfe\u3057\u3066\u9632\u5fa1\u7684\u306b\u5bfe\u5fdc\u3059\u308b\u3053\u3068\u3067\u3001\u30b7\u30b9\u30c6\u30e0\u306e\u5805\u7262\u6027\u3092\u9ad8\u3081\u3089\u308c\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class ExternalAPIClient\n  class APIError &lt; StandardError; end\n\n  def fetch_data(endpoint)\n    retries = 0\n    begin\n      response = HTTP.get(endpoint)\n      raise APIError, \"\u4e0d\u6b63\u306a\u30ec\u30b9\u30dd\u30f3\u30b9\" unless response.success?\n      JSON.parse(response.body)\n    rescue HTTP::Error =&gt; e\n      retries += 1\n      if retries &lt;= 3\n        sleep(2 ** retries)  # \u6307\u6570\u30d0\u30c3\u30af\u30aa\u30d5\n        retry\n      else\n        raise APIError, \"API\u30ea\u30af\u30a8\u30b9\u30c8\u306b\u5931\u6557\u3057\u307e\u3057\u305f: #{e.message}\"\n      end\n    rescue JSON::ParserError =&gt; e\n      raise APIError, \"JSON\u306e\u30d1\u30fc\u30b9\u306b\u5931\u6557\u3057\u307e\u3057\u305f: #{e.message}\"\n    end\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-8\">4. \u30e1\u30c3\u30bb\u30fc\u30b8\u3068\u30d0\u30c3\u30af\u30c8\u30ec\u30fc\u30b9\u306e\u52b9\u679c\u7684\u306a\u6d3b\u7528<\/h3>\n\n\n\n<p>\u4f8b\u5916\u306e\u30e1\u30c3\u30bb\u30fc\u30b8\u3068\u30d0\u30c3\u30af\u30c8\u30ec\u30fc\u30b9\u3092\u52b9\u679c\u7684\u306b\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u30c7\u30d0\u30c3\u30b0\u6642\u306e\u554f\u984c\u7279\u5b9a\u3092\u5bb9\u6613\u306b\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class DatabaseConnection\n  def connect(config)\n    begin\n      # \u63a5\u7d9a\u51e6\u7406\n    rescue =&gt; e\n      # \u5143\u306e\u4f8b\u5916\u3092\u4fdd\u6301\u3057\u306a\u304c\u3089\u3001\u3088\u308a\u8a73\u7d30\u306a\u60c5\u5831\u3092\u4ed8\u52a0\n      raise DatabaseError.new(\n        \"\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u63a5\u7d9a\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002\u8a2d\u5b9a: #{config.inspect}\",\n        cause: e\n      )\n    end\n  end\nend\n\n# \u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u6642\u306b\u30d0\u30c3\u30af\u30c8\u30ec\u30fc\u30b9\u3092\u6d3b\u7528\nbegin\n  db.connect(config)\nrescue DatabaseError =&gt; e\n  logger.error \"DB\u63a5\u7d9a\u30a8\u30e9\u30fc: #{e.message}\"\n  logger.error \"\u539f\u56e0: #{e.cause.message}\" if e.cause\n  logger.error \"\u30d0\u30c3\u30af\u30c8\u30ec\u30fc\u30b9:\\n#{e.backtrace.join(\"\\n\")}\"\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-9\">5. \u4f8b\u5916\u51e6\u7406\u3092\u4f7f\u3063\u305f\u30ac\u30fc\u30c9\u7bc0\u30d1\u30bf\u30fc\u30f3<\/h3>\n\n\n\n<p>\u30e1\u30bd\u30c3\u30c9\u306e\u5148\u982d\u3067\u4e0d\u6b63\u306a\u5165\u529b\u3092\u30c1\u30a7\u30c3\u30af\u3057\u3001\u65e9\u671f\u306b\u30ea\u30bf\u30fc\u30f3\u307e\u305f\u306f\u4f8b\u5916\u3092\u767a\u751f\u3055\u305b\u308b\u3053\u3068\u3067\u3001\u30b3\u30fc\u30c9\u306e\u53ef\u8aad\u6027\u3092\u5411\u4e0a\u3055\u305b\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class Order\n  def process_order(cart, user)\n    # \u30ac\u30fc\u30c9\u7bc0\u306b\u3088\u308b\u5165\u529b\u691c\u8a3c\n    raise ArgumentError, \"\u30ab\u30fc\u30c8\u304c\u7a7a\u3067\u3059\" if cart.empty?\n    raise ArgumentError, \"\u30e6\u30fc\u30b6\u30fc\u304c\u672a\u30ed\u30b0\u30a4\u30f3\u3067\u3059\" unless user.logged_in?\n    raise ValidationError, \"\u652f\u6255\u3044\u65b9\u6cd5\u304c\u672a\u8a2d\u5b9a\u3067\u3059\" unless user.payment_method?\n\n    # \u30e1\u30a4\u30f3\u306e\u51e6\u7406\u30ed\u30b8\u30c3\u30af\n    process_payment(cart.total, user.payment_method)\n    create_order_record(cart, user)\n    send_confirmation_email(user)\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-10\">6. \u5916\u90e8\u30e9\u30a4\u30d6\u30e9\u30ea\u3068\u306e\u9023\u643a\u6642\u306e\u4f8b\u5916\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0<\/h3>\n\n\n\n<p>\u5916\u90e8\u30e9\u30a4\u30d6\u30e9\u30ea\u306e\u4f8b\u5916\u3092\u9069\u5207\u306b\u5909\u63db\u3059\u308b\u3053\u3068\u3067\u3001\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u5168\u4f53\u3067\u4e00\u8cab\u3057\u305f\u4f8b\u5916\u51e6\u7406\u304c\u53ef\u80fd\u306b\u306a\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class PaymentService\n  def process_stripe_payment(token, amount)\n    Stripe::Charge.create(\n      amount: amount,\n      currency: 'jpy',\n      source: token\n    )\n  rescue Stripe::CardError =&gt; e\n    raise PaymentError.new(\"\u30ab\u30fc\u30c9\u6c7a\u6e08\u306b\u5931\u6557\u3057\u307e\u3057\u305f: #{e.message}\")\n  rescue Stripe::RateLimitError =&gt; e\n    raise ServiceUnavailableError.new(\"\u30b5\u30fc\u30d3\u30b9\u304c\u4e00\u6642\u7684\u306b\u5229\u7528\u3067\u304d\u307e\u305b\u3093\")\n  rescue Stripe::APIError =&gt; e\n    raise ExternalServiceError.new(\"\u6c7a\u6e08\u30b5\u30fc\u30d3\u30b9\u3067\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\")\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-11\">7. \u30c6\u30b9\u30c8\u99c6\u52d5\u958b\u767a\u306b\u304a\u3051\u308braise\u306e\u6d3b\u7528<\/h3>\n\n\n\n<p>\u4f8b\u5916\u306e\u767a\u751f\u3092\u671f\u5f85\u3059\u308b\u30c6\u30b9\u30c8\u3092\u66f8\u304f\u3053\u3068\u3067\u3001\u30a8\u30e9\u30fc\u51e6\u7406\u306e\u52d5\u4f5c\u3092\u78ba\u5b9f\u306b\u691c\u8a3c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">require 'rspec'\n\nRSpec.describe PaymentProcessor do\n  describe '#process_payment' do\n    it '\u4e0d\u6b63\u306a\u91d1\u984d\u3067\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3059\u308b\u3053\u3068' do\n      processor = PaymentProcessor.new\n\n      expect {\n        processor.process_payment(-1000, 'JPY')\n      }.to raise_error(ArgumentError, \/\u91d1\u984d\u306f\u6b63\u306e\u6570\u3067\u3042\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\/)\n    end\n\n    it '\u4e0d\u6b63\u306a\u901a\u8ca8\u30b3\u30fc\u30c9\u3067\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3059\u308b\u3053\u3068' do\n      processor = PaymentProcessor.new\n\n      expect {\n        processor.process_payment(1000, 'INVALID')\n      }.to raise_error(ArgumentError, \/\u4e0d\u6b63\u306a\u901a\u8ca8\u30b3\u30fc\u30c9\/)\n    end\n  end\nend<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5b9f\u8df5\u7684\u306a\u4f7f\u3044\u65b9\u3092\u9069\u6750\u9069\u6240\u3067\u6d3b\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u5805\u7262\u3067\u4fdd\u5b88\u6027\u306e\u9ad8\u3044\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u958b\u767a\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-12\">\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-13\">\u6b63\u3057\u3044\u7c92\u5ea6\u3067\u306e\u4f8b\u5916\u8a2d\u8a08\u306e\u91cd\u8981\u6027<\/h3>\n\n\n\n<p>\u9069\u5207\u306a\u7c92\u5ea6\u3067\u4f8b\u5916\u3092\u8a2d\u8a08\u3059\u308b\u3053\u3068\u306f\u3001\u4fdd\u5b88\u6027\u306e\u9ad8\u3044\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u69cb\u7bc9\u3059\u308b\u4e0a\u3067\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u60aa\u3044\u4f8b\uff1a\u7c92\u5ea6\u304c\u7c97\u3059\u304e\u308b\nclass ApplicationError &lt; StandardError; end\n\n# \u826f\u3044\u4f8b\uff1a\u9069\u5207\u306a\u7c92\u5ea6\u3067\u306e\u4f8b\u5916\u968e\u5c64\nmodule MyApp\n  class Error &lt; StandardError; end\n\n  class DatabaseError &lt; Error; end\n  class ValidationError &lt; Error; end\n  class AuthenticationError &lt; Error; end\n\n  module Payment\n    class PaymentError &lt; Error; end\n    class InsufficientFundsError &lt; PaymentError; end\n    class CardDeclinedError &lt; PaymentError; end\n  end\nend\n\n# \u4f7f\u7528\u4f8b\ndef process_payment(user, amount)\n  raise MyApp::Payment::InsufficientFundsError if user.balance &lt; amount\n  # \u652f\u6255\u3044\u51e6\u7406\nrescue MyApp::Payment::CardDeclinedError =&gt; e\n  # \u30ab\u30fc\u30c9\u6c7a\u6e08\u5931\u6557\u6642\u306e\u51e6\u7406\nrescue MyApp::Payment::PaymentError =&gt; e\n  # \u305d\u306e\u4ed6\u306e\u652f\u6255\u3044\u95a2\u9023\u30a8\u30e9\u30fc\u306e\u51e6\u7406\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-14\">rescue\/ensure\/else\u30d6\u30ed\u30c3\u30af\u306e\u5229\u7528<\/h3>\n\n\n\n<p>rescue\/ensure\/else\u30d6\u30ed\u30c3\u30af\u3092\u9069\u5207\u306b\u7d44\u307f\u5408\u308f\u305b\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u5805\u7262\u306a\u30a8\u30e9\u30fc\u51e6\u7406\u304c\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">def process_transaction\n  begin\n    # \u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u958b\u59cb\n    ActiveRecord::Base.transaction do\n      # \u30e1\u30a4\u30f3\u51e6\u7406\n      process_payment\n      update_inventory\n      send_notification\n    end\n  rescue ActiveRecord::RecordInvalid =&gt; e\n    # \u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc\u306e\u51e6\u7406\n    log_error(e)\n    notify_admin(e)\n    raise\n  rescue StandardError =&gt; e\n    # \u305d\u306e\u4ed6\u306e\u30a8\u30e9\u30fc\u51e6\u7406\n    rollback_changes\n    raise\n  else\n    # \u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u306a\u304b\u3063\u305f\u5834\u5408\u306e\u51e6\u7406\n    notify_success\n  ensure\n    # \u5fc5\u305a\u5b9f\u884c\u3055\u308c\u308b\u5f8c\u51e6\u7406\n    cleanup_resources\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-15\">\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u3092\u8003\u616e\u3057\u305f\u30a8\u30e9\u30fc\u51e6\u7406\u306e\u5b9f\u88c5<\/h3>\n\n\n\n<p>\u4f8b\u5916\u51e6\u7406\u306f\u30d1\u30d5\u30a9\u30fc\u30de\u30f3\u30b9\u306b\u5f71\u97ff\u3092\u4e0e\u3048\u308b\u53ef\u80fd\u6027\u304c\u3042\u308b\u305f\u3081\u3001\u9069\u5207\u306a\u4f7f\u7528\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class UserService\n  # \u60aa\u3044\u4f8b\uff1a\u4f8b\u5916\u3092\u5236\u5fa1\u30d5\u30ed\u30fc\u3068\u3057\u3066\u4f7f\u7528\n  def find_user_bad(id)\n    begin\n      User.find(id)\n    rescue ActiveRecord::RecordNotFound\n      User.new\n    end\n  end\n\n  # \u826f\u3044\u4f8b\uff1a\u6761\u4ef6\u5206\u5c90\u3092\u4f7f\u7528\n  def find_user_good(id)\n    User.exists?(id) ? User.find(id) : User.new\n  end\n\n  # \u9069\u5207\u306a\u4f8b\u5916\u51e6\u7406\u306e\u4f8b\n  def process_user_data(user)\n    # \u4e8b\u524d\u6761\u4ef6\u306e\u30c1\u30a7\u30c3\u30af\n    return false unless user.valid?\n\n    begin\n      # \u30af\u30ea\u30c6\u30a3\u30ab\u30eb\u306a\u51e6\u7406\u306e\u307f\u3092\u4f8b\u5916\u51e6\u7406\u3067\u56f2\u3080\n      user.save!\n      send_welcome_email(user)\n      true\n    rescue ActiveRecord::RecordInvalid =&gt; e\n      log_error(e)\n      false\n    rescue Net::SMTPError =&gt; e\n      # \u30e1\u30fc\u30eb\u9001\u4fe1\u5931\u6557\u306f\u8a18\u9332\u3059\u308b\u304c\u3001\u51e6\u7406\u306f\u7d9a\u884c\n      log_warning(e)\n      true\n    end\n  end\nend<\/pre>\n\n\n\n<p>\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u306e\u5b9f\u88c5\u30dd\u30a4\u30f3\u30c8\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u4f8b\u5916\u306e\u9069\u5207\u306a\u4f7f\u7528<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u4e88\u671f\u305b\u306c\u30a8\u30e9\u30fc\u306e\u51e6\u7406\u306b\u306f\u4f8b\u5916\u3092\u4f7f\u7528<\/li>\n\n\n\n<li>\u901a\u5e38\u306e\u5236\u5fa1\u30d5\u30ed\u30fc\u306b\u306f\u6761\u4ef6\u5206\u5c90\u3092\u4f7f\u7528<\/li>\n\n\n\n<li>\u30d3\u30b8\u30cd\u30b9\u30ed\u30b8\u30c3\u30af\u306e\u30a8\u30e9\u30fc\u306b\u306f\u9069\u5207\u306a\u623b\u308a\u5024\u3092\u4f7f\u7528<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ea\u30bd\u30fc\u30b9\u7ba1\u7406<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>ensure<\/code>\u30d6\u30ed\u30c3\u30af\u3067\u30ea\u30bd\u30fc\u30b9\u306e\u78ba\u5b9f\u306a\u89e3\u653e<\/li>\n\n\n\n<li>\u30c8\u30e9\u30f3\u30b6\u30af\u30b7\u30e7\u30f3\u306e\u9069\u5207\u306a\u7ba1\u7406<\/li>\n\n\n\n<li>\u30b3\u30cd\u30af\u30b7\u30e7\u30f3\u30d7\u30fc\u30eb\u306e\u9069\u5207\u306a\u7ba1\u7406<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30ed\u30b0\u3068\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u30a8\u30e9\u30fc\u306e\u9069\u5207\u306a\u30ed\u30b0\u8a18\u9332<\/li>\n\n\n\n<li>\u91cd\u8981\u306a\u30a8\u30e9\u30fc\u306e\u901a\u77e5\u8a2d\u5b9a<\/li>\n\n\n\n<li>\u30a8\u30e9\u30fc\u767a\u751f\u7b87\u6240\u306e\u7279\u5b9a\u304c\u5bb9\u6613\u306a\u60c5\u5831\u306e\u8a18\u9332<\/li>\n<\/ul>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u30a8\u30e9\u30fc\u306e\u4f1d\u64ad<\/strong><\/li>\n<\/ol>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u9069\u5207\u306a\u4f8b\u5916\u306e\u5909\u63db<\/li>\n\n\n\n<li>\u610f\u5473\u306e\u3042\u308b\u4f8b\u5916\u30e1\u30c3\u30bb\u30fc\u30b8<\/li>\n\n\n\n<li>\u30b9\u30bf\u30c3\u30af\u30c8\u30ec\u30fc\u30b9\u306e\u4fdd\u6301<\/li>\n<\/ul>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9\u3092\u610f\u8b58\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u4fdd\u5b88\u6027\u304c\u9ad8\u304f\u3001\u5b89\u5b9a\u3057\u305f\u30a2\u30d7\u30ea\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u958b\u767a\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-16\">\u3088\u304f\u3042\u308b\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\u3068\u6539\u5584\u65b9\u6cd5<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-17\">\u907f\u3051\u308b\u3079\u304d\u4f8b\u5916\u51e6\u7406\u306e\u5b9f\u88c5\u30d1\u30bf\u30fc\u30f3<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u7a7a\u306erescue\u30d6\u30ed\u30c3\u30af<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\uff1a\u30a8\u30e9\u30fc\u3092\u9ed9\u3063\u3066\u7121\u8996\u3059\u308b\nbegin\n  some_dangerous_operation\nrescue StandardError\n  # \u4f55\u3082\u3057\u306a\u3044 - \u5371\u967a\uff01\nend\n\n# \u6539\u5584\u4f8b\uff1a\u9069\u5207\u306a\u30a8\u30e9\u30fc\u30ed\u30b0\u3068\u51e6\u7406\nbegin\n  some_dangerous_operation\nrescue StandardError =&gt; e\n  logger.error \"\u64cd\u4f5c\u306b\u5931\u6557\u3057\u307e\u3057\u305f: #{e.message}\"\n  notify_admin if critical_operation?\n  raise # \u5fc5\u8981\u306b\u5fdc\u3058\u3066\u4e0a\u4f4d\u5c64\u306b\u518d\u5ea6\u767a\u751f\u3055\u305b\u308b\nend<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u4f8b\u5916\u30af\u30e9\u30b9\u306e\u904e\u5270\u306a\u6355\u6349<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\uff1a\u5168\u3066\u306e\u4f8b\u5916\u3092\u6355\u6349\u3059\u308b\nbegin\n  process_data\nrescue Exception =&gt; e  # Exception \u306f\u4f7f\u308f\u306a\u3044\uff01\n  logger.error(e)\nend\n\n# \u6539\u5584\u4f8b\uff1a\u5fc5\u8981\u306a\u4f8b\u5916\u306e\u307f\u3092\u6355\u6349\nbegin\n  process_data\nrescue StandardError =&gt; e  # StandardError \u3068\u305d\u306e\u5b50\u30af\u30e9\u30b9\u306e\u307f\u6355\u6349\n  logger.error(e)\nrescue SystemCallError =&gt; e  # \u5fc5\u8981\u306b\u5fdc\u3058\u3066\u7279\u5b9a\u306e\u4f8b\u5916\u3092\u500b\u5225\u306b\u6355\u6349\n  handle_system_error(e)\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-18\">\u30ea\u30d5\u30a1\u30af\u30bf\u30ea\u30f3\u30b0\u306b\u3088\u308b\u6539\u5584\u4f8b\u306e\u7d39\u4ecb<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>\u5236\u5fa1\u30d5\u30ed\u30fc\u3068\u3057\u3066\u306e\u4f8b\u5916\u4f7f\u7528\u306e\u6539\u5584<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\uff1a\u5236\u5fa1\u30d5\u30ed\u30fc\u3068\u3057\u3066\u4f8b\u5916\u3092\u4f7f\u7528\ndef find_user(id)\n  begin\n    User.find(id)\n  rescue ActiveRecord::RecordNotFound\n    nil\n  end\nend\n\n# \u6539\u5584\u4f8b\uff1a\u6761\u4ef6\u5206\u5c90\u306b\u3088\u308b\u660e\u793a\u7684\u306a\u5236\u5fa1\ndef find_user(id)\n  User.exists?(id) ? User.find(id) : nil\nend<\/pre>\n\n\n\n<ol start=\"2\" class=\"wp-block-list\">\n<li><strong>\u4f8b\u5916\u51e6\u7406\u306e\u8cac\u52d9\u5206\u96e2<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\uff1a\u4f8b\u5916\u51e6\u7406\u304c\u6df7\u5728\u3057\u3066\u3044\u308b\ndef process_order\n  begin\n    charge_credit_card\n    update_inventory\n    send_email\n  rescue CreditCardError =&gt; e\n    logger.error(e)\n    notify_admin\n    refund_payment\n  rescue InventoryError =&gt; e\n    logger.error(e)\n    restock_items\n  rescue EmailError =&gt; e\n    logger.error(e)\n    queue_email_retry\n  end\nend\n\n# \u6539\u5584\u4f8b\uff1a\u8cac\u52d9\u306e\u5206\u96e2\nclass OrderProcessor\n  def process\n    with_transaction do\n      payment = PaymentService.new.charge\n      inventory = InventoryService.new.update\n      NotificationService.new.send_email\n    end\n  end\n\n  private\n\n  def with_transaction\n    ActiveRecord::Base.transaction { yield }\n  rescue StandardError =&gt; e\n    ErrorHandler.handle(e)\n    raise\n  end\nend\n\nclass ErrorHandler\n  def self.handle(error)\n    case error\n    when CreditCardError then handle_payment_error(error)\n    when InventoryError then handle_inventory_error(error)\n    when EmailError then handle_email_error(error)\n    end\n  end\nend<\/pre>\n\n\n\n<ol start=\"3\" class=\"wp-block-list\">\n<li><strong>\u4f8b\u5916\u30e1\u30c3\u30bb\u30fc\u30b8\u306e\u6539\u5584<\/strong><\/li>\n<\/ol>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># \u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\uff1a\u4e0d\u660e\u78ba\u306a\u30a8\u30e9\u30fc\u30e1\u30c3\u30bb\u30fc\u30b8\nraise \"\u30a8\u30e9\u30fc\u304c\u767a\u751f\u3057\u307e\u3057\u305f\"\n\n# \u6539\u5584\u4f8b\uff1a\u5177\u4f53\u7684\u3067\u6709\u7528\u306a\u60c5\u5831\u3092\u542b\u3080\u30e1\u30c3\u30bb\u30fc\u30b8\nraise ValidationError.new(\n  \"\u30e6\u30fc\u30b6\u30fc\u306e\u4f5c\u6210\u306b\u5931\u6557\u3057\u307e\u3057\u305f\",\n  details: {\n    field: \"email\",\n    value: email,\n    reason: \"\u65e2\u306b\u767b\u9332\u3055\u308c\u3066\u3044\u308b\u30e1\u30fc\u30eb\u30a2\u30c9\u30ec\u30b9\u3067\u3059\"\n  }\n)<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u30a2\u30f3\u30c1\u30d1\u30bf\u30fc\u30f3\u3092\u8a8d\u8b58\u3057\u3001\u9069\u5207\u306a\u6539\u5584\u65b9\u6cd5\u3092\u9069\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u3088\u308a\u4fdd\u5b88\u6027\u304c\u9ad8\u304f\u3001\u30d0\u30b0\u306e\u5c11\u306a\u3044\u30b3\u30fc\u30c9\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"i-19\">\u5b9f\u8df5\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9\u5225\u5b9f\u88c5\u4f8b<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-20\">WebAPI \u306e\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u5b9f\u88c5<\/h3>\n\n\n\n<p>REST API\u3067\u306f\u3001\u9069\u5207\u306a\u30b9\u30c6\u30fc\u30bf\u30b9\u30b3\u30fc\u30c9\u3068\u30a8\u30e9\u30fc\u30ec\u30b9\u30dd\u30f3\u30b9\u306e\u5f62\u5f0f\u3092\u5b9a\u7fa9\u3059\u308b\u3053\u3068\u304c\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># API\u306e\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u4f8b\nclass API::V1::BaseController &lt; ApplicationController\n  rescue_from StandardError do |e|\n    render_error(500, \"Internal Server Error\", e)\n  end\n\n  rescue_from ActiveRecord::RecordNotFound do |e|\n    render_error(404, \"Resource Not Found\", e)\n  end\n\n  rescue_from ActiveRecord::RecordInvalid do |e|\n    render_error(422, \"Validation Error\", e)\n  end\n\n  private\n\n  def render_error(status, message, exception)\n    error_response = {\n      status: status,\n      message: message,\n      details: exception.message,\n      errors: exception.respond_to?(:record) ? \n              exception.record.errors.full_messages : \n              nil\n    }\n\n    # \u958b\u767a\u74b0\u5883\u306e\u5834\u5408\u306f\u30b9\u30bf\u30c3\u30af\u30c8\u30ec\u30fc\u30b9\u3082\u542b\u3081\u308b\n    if Rails.env.development?\n      error_response[:backtrace] = exception.backtrace\n    end\n\n    render json: error_response, status: status\n  end\nend\n\n# \u5b9f\u88c5\u4f8b\nclass API::V1::UsersController &lt; API::V1::BaseController\n  def create\n    user = User.new(user_params)\n    if user.save\n      render json: user, status: :created\n    else\n      raise ActiveRecord::RecordInvalid.new(user)\n    end\n  rescue ActiveRecord::RecordNotUnique\n    render_error(409, \"User already exists\", \"Email address is already taken\")\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-21\">\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9 \u30aa\u30da\u30ec\u30fc\u30b7\u30e7\u30f3\u6642\u306e\u4f8b\u5916\u51e6\u7406<\/h3>\n\n\n\n<p>\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u64cd\u4f5c\u6642\u306e\u4f8b\u5916\u51e6\u7406\u306f\u3001\u30c7\u30fc\u30bf\u306e\u6574\u5408\u6027\u3092\u4fdd\u3064\u305f\u3081\u306b\u7279\u306b\u91cd\u8981\u3067\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class UserService\n  class DatabaseError &lt; StandardError; end\n\n  def update_user_with_profile(user_id, profile_params)\n    ActiveRecord::Base.transaction do\n      user = User.lock.find(user_id)\n      profile = user.profile || user.build_profile\n\n      update_profile(profile, profile_params)\n      update_search_index(user)\n      notify_updates(user)\n\n      true\n    end\n  rescue ActiveRecord::RecordNotFound =&gt; e\n    raise DatabaseError.new(\"\u30e6\u30fc\u30b6\u30fc\u304c\u898b\u3064\u304b\u308a\u307e\u305b\u3093: #{e.message}\")\n  rescue ActiveRecord::StaleObjectError =&gt; e\n    raise DatabaseError.new(\"\u697d\u89b3\u7684\u30ed\u30c3\u30af\u30a8\u30e9\u30fc: #{e.message}\")\n  rescue ActiveRecord::RecordInvalid =&gt; e\n    raise DatabaseError.new(\"\u30d0\u30ea\u30c7\u30fc\u30b7\u30e7\u30f3\u30a8\u30e9\u30fc: #{e.message}\")\n  rescue StandardError =&gt; e\n    Rollbar.error(e)  # \u30a8\u30e9\u30fc\u76e3\u8996\u30b5\u30fc\u30d3\u30b9\u3078\u306e\u901a\u77e5\n    raise DatabaseError.new(\"\u30c7\u30fc\u30bf\u30d9\u30fc\u30b9\u64cd\u4f5c\u30a8\u30e9\u30fc: #{e.message}\")\n  end\n\n  private\n\n  def update_profile(profile, params)\n    unless profile.update(params)\n      raise ActiveRecord::RecordInvalid.new(profile)\n    end\n  end\n\n  def update_search_index(user)\n    SearchIndexWorker.perform_async(user.id)\n  rescue Redis::CannotConnectError =&gt; e\n    # \u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u30b8\u30e7\u30d6\u306e\u30a8\u30e9\u30fc\u306f\u8a18\u9332\u3059\u308b\u304c\u3001\u30e1\u30a4\u30f3\u51e6\u7406\u306f\u7d99\u7d9a\n    logger.error \"\u691c\u7d22\u30a4\u30f3\u30c7\u30c3\u30af\u30b9\u66f4\u65b0\u306e\u30ad\u30e5\u30fc\u30a4\u30f3\u30b0\u306b\u5931\u6557: #{e.message}\"\n  end\n\n  def notify_updates(user)\n    NotificationService.notify_profile_update(user)\n  rescue NotificationError =&gt; e\n    # \u901a\u77e5\u5931\u6557\u306f\u8a18\u9332\u3059\u308b\u304c\u3001\u30e1\u30a4\u30f3\u51e6\u7406\u306f\u7d99\u7d9a\n    logger.warn \"\u30d7\u30ed\u30d5\u30a3\u30fc\u30eb\u66f4\u65b0\u901a\u77e5\u306e\u9001\u4fe1\u306b\u5931\u6557: #{e.message}\"\n  end\nend<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"i-22\">\u975e\u540c\u671f\u51e6\u7406\u306b\u304a\u3051\u308b\u30a8\u30e9\u30fc\u51e6\u7406<\/h3>\n\n\n\n<p>\u30d0\u30c3\u30af\u30b0\u30e9\u30a6\u30f3\u30c9\u30b8\u30e7\u30d6\u3067\u306e\u30a8\u30e9\u30fc\u51e6\u7406\u306f\u3001\u30b8\u30e7\u30d6\u306e\u518d\u8a66\u884c\u6226\u7565\u3092\u8003\u616e\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">class ImportDataWorker\n  include Sidekiq::Worker\n\n  sidekiq_options retry: 3, dead: false\n\n  RETRY_ERRORS = [\n    Aws::S3::Errors::ServiceError,\n    Net::OpenTimeout,\n    Redis::TimeoutError\n  ].freeze\n\n  def perform(import_id)\n    import = Import.find(import_id)\n    import.update!(status: :processing)\n\n    begin\n      data = fetch_data(import)\n      process_data(data, import)\n      import.update!(status: :completed)\n    rescue *RETRY_ERRORS =&gt; e\n      # \u518d\u8a66\u884c\u53ef\u80fd\u306a\u30a8\u30e9\u30fc\n      handle_retryable_error(e, import)\n      raise # Sidekiq\u306b\u518d\u8a66\u884c\u3055\u305b\u308b\n    rescue StandardError =&gt; e\n      # \u518d\u8a66\u884c\u4e0d\u53ef\u80fd\u306a\u30a8\u30e9\u30fc\n      handle_fatal_error(e, import)\n    end\n  end\n\n  private\n\n  def handle_retryable_error(error, import)\n    retries = retry_count || 0\n\n    import.update!(\n      status: :retrying,\n      error_message: error.message,\n      retry_count: retries + 1\n    )\n\n    # \u30a8\u30e9\u30fc\u76e3\u8996\u30b5\u30fc\u30d3\u30b9\u3078\u306e\u901a\u77e5\n    Rollbar.warning(\n      error,\n      import_id: import.id,\n      retry_count: retries\n    )\n  end\n\n  def handle_fatal_error(error, import)\n    import.update!(\n      status: :failed,\n      error_message: error.message\n    )\n\n    # \u7ba1\u7406\u8005\u3078\u306e\u901a\u77e5\n    AdminNotifier.notify_import_failure(\n      import,\n      error.message\n    )\n\n    # \u30a8\u30e9\u30fc\u76e3\u8996\u30b5\u30fc\u30d3\u30b9\u3078\u306e\u901a\u77e5\n    Rollbar.error(\n      error,\n      import_id: import.id,\n      final_failure: true\n    )\n  end\nend<\/pre>\n\n\n\n<p>\u3053\u308c\u3089\u306e\u5b9f\u88c5\u4f8b\u306f\u3001\u5b9f\u969b\u306e\u30d7\u30ed\u30c0\u30af\u30b7\u30e7\u30f3\u74b0\u5883\u3067\u4f7f\u7528\u3055\u308c\u308b\u4e00\u822c\u7684\u306a\u30d1\u30bf\u30fc\u30f3\u3092\u793a\u3057\u3066\u3044\u307e\u3059\u3002\u72b6\u6cc1\u306b\u5fdc\u3058\u3066\u9069\u5207\u306b\u30ab\u30b9\u30bf\u30de\u30a4\u30ba\u3057\u3066\u4f7f\u7528\u3059\u308b\u3053\u3068\u3067\u3001\u5805\u7262\u306a\u30a8\u30e9\u30fc\u30cf\u30f3\u30c9\u30ea\u30f3\u30b0\u3092\u5b9f\u73fe\u3067\u304d\u307e\u3059\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Warning: Undefined array key &#8220;is_admin&#8221; in \/home\/xs392991\/dexall.co.jp\/public_html\/articles\/wp-content\/themes\/ &#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[],"class_list":{"0":"post-1499","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-ruby","7":"nothumb"},"_links":{"self":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/1499","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1499"}],"version-history":[{"count":1,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/1499\/revisions"}],"predecessor-version":[{"id":1500,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=\/wp\/v2\/posts\/1499\/revisions\/1500"}],"wp:attachment":[{"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1499"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1499"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dexall.co.jp\/articles\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1499"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}