<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Juhee Kang</title>
    <description>The latest articles on DEV Community by Juhee Kang (@claudiajkang).</description>
    <link>https://dev.to/claudiajkang</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F596394%2F3b2cab9b-1d3c-43c0-90e3-1a045b7aae50.png</url>
      <title>DEV Community: Juhee Kang</title>
      <link>https://dev.to/claudiajkang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/claudiajkang"/>
    <language>en</language>
    <item>
      <title>Control flow: try-catch or if-else?</title>
      <dc:creator>Juhee Kang</dc:creator>
      <pubDate>Tue, 06 Apr 2021 12:03:01 +0000</pubDate>
      <link>https://dev.to/claudiajkang/control-flow-try-catch-or-if-else-4hfl</link>
      <guid>https://dev.to/claudiajkang/control-flow-try-catch-or-if-else-4hfl</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Lately, while working on a new project, I had a chance to think about the proper way to handle control flow. As all developers might know well, the most common approaches used are &lt;code&gt;try-catch&lt;/code&gt; and &lt;code&gt;if-else&lt;/code&gt;. So far, I haven't thought deeply about the difference between these two. From time to time, I think I mainly adopted a more concise way of writing code. Stability was significant on this project, applying the appropriate control flow processing approach was one of the keys. For this reason, I wrote pseudocode based on the scenario for these two approaches and compared them, and I'd like to share the result with this community.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario
&lt;/h3&gt;

&lt;p&gt;Suppose that the signup logic of the virtual Web service 'A' is not allowed to have duplicate nicknames, e-mails, and phones.&lt;/p&gt;

&lt;p&gt;The signup verification process is as follows:&lt;br&gt;
    1. Check for duplicate nickname.&lt;br&gt;
    2. Check duplicate on personal information.&lt;br&gt;
        a. Verify email address is unique.&lt;br&gt;
        b. Verify phone number is unique.&lt;/p&gt;

&lt;p&gt;The code below is an implementation of this logic.(I've excluded error-handling logic at here on purpose.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// signUp.js &lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;signUp&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;      &lt;span class="c1"&gt;// function of signup&lt;/span&gt;
     &lt;span class="nx"&gt;userTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nickname&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Check for duplicate nickname.&lt;/span&gt;
     &lt;span class="nx"&gt;duplicateDetailInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Check duplicate on personal information. &lt;/span&gt;
     &lt;span class="nx"&gt;addUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Add a user&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="c1"&gt;// duplicateDetailInfo.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;duplicateDetailInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;userTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Verify email address is unique.&lt;/span&gt;
    &lt;span class="nx"&gt;userTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Verify phone number is unique.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="c1"&gt;// userTable.js&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;userTable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="c1"&gt;// Will be implemented according to each approach&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although it's not perfect, I purposely wrote the code to explain the difference in control flow.&lt;/p&gt;

&lt;h4&gt;
  
  
  On this code, depending on how to implement  &lt;code&gt;userTable.isUnique&lt;/code&gt;as Exception or return values(false, null, etc..), I will explain using &lt;code&gt;try-catch&lt;/code&gt; and &lt;code&gt;if-else&lt;/code&gt;, respectively.
&lt;/h4&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;try-catch&lt;/code&gt; Exception
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;On this implementation approach, &lt;code&gt;userTable.isUnique()&lt;/code&gt; will raise an error if the value exists.&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// signup.js &lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;signUp&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
     &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
         &lt;span class="nx"&gt;userTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nickname&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// Raise Exception if the nickname is not unique.&lt;/span&gt;
         &lt;span class="nx"&gt;duplicateDetailInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Check for duplicate personal information.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fail&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;addUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="c1"&gt;// duplicateDetailInfo.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;duplicateDetailInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nx"&gt;userTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Raise Exception if the email is not unique.&lt;/span&gt;
    &lt;span class="nx"&gt;userTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Raise Exception if the phone is not unique.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// userTable.js&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;userTable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Raise Exception if the value is not unique.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The problem with this approach is that the flow of processing is not explicitly visible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;signUp&lt;span class="o"&gt;()&lt;/span&gt;
├── try
│   ├── .isUnique&lt;span class="o"&gt;(&lt;/span&gt;nickname&lt;span class="o"&gt;)&lt;/span&gt;
│   │    └── raise Exception
│   │   
│   └── duplicateDetailInfo&lt;span class="o"&gt;()&lt;/span&gt;
│       ├── .isUnique&lt;span class="o"&gt;(&lt;/span&gt;email&lt;span class="o"&gt;)&lt;/span&gt;
│       │    └── raise Exception
│       │   
│       └── .isUnique&lt;span class="o"&gt;(&lt;/span&gt;phone&lt;span class="o"&gt;)&lt;/span&gt;
│            └── raise Exception
│           
└── catch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, the nickname exception is processed by the parent function (signUp), so you can easily find the order of the control flow. However, for email and phone exceptions, it is difficult to identify the control flow because it is not easy to know where to handle the exceptions. &lt;/p&gt;

&lt;p&gt;This code consists of two depths, so it is easy to verify, but it is not known what happens to the control flow after this line code. In case when &lt;code&gt;try-catch&lt;/code&gt; is used multiple times, it will become harder to figure out the control flow. Furthermore, code will be less intuitive.&lt;/p&gt;

&lt;p&gt;Of course, this &lt;code&gt;try-catch&lt;/code&gt; approach has the advantage of being able to handle all exceptions in one place. But, this can be a disadvantage. However, if there are hundreds of exceptions, the code may also be less intuitive because &lt;strong&gt;different exception logic is handled in a single location.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  if - else
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;On this implementation approach, &lt;code&gt;userTable.isUnique()&lt;/code&gt; will return true if the value exists.&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// signup.js &lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;signUp&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;userTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nickname&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;    &lt;span class="c1"&gt;// Return false if the nickname is not unique.&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fail&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;   
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;duplicateDetailInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// Return false if the details is not unique.&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fail&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;addUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;  

&lt;span class="c1"&gt;// duplicateDetailInfo.js&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;duplicateDetailInfo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;userTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;        &lt;span class="c1"&gt;// Return false if the email is duplicated.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userTable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;phone&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;         &lt;span class="c1"&gt;// Return false if the phone is duplicated.&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// userTable.js&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;userTable&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;isUnique&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
        &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userDB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;// Return false if the value is not unique.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this approach, &lt;strong&gt;predictable and formatting can safely implement code&lt;/strong&gt; is an advantage.&lt;/p&gt;

&lt;p&gt;The advantage of this approach is that it can predict the flow of code and implement the code by specifying the return type(in this case, boolean). Since &lt;code&gt;try-catch&lt;/code&gt; statement is not used, the control flow can be easily to figure out because it is handlded directly from a parent function rather than from another location(exception catch). By this benefit, it is usally possible to check quickly even if something goes wrong.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;signUp&lt;span class="o"&gt;()&lt;/span&gt;
├── .isUnique&lt;span class="o"&gt;(&lt;/span&gt;nickname&lt;span class="o"&gt;)&lt;/span&gt;
│    └── &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;? &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; handling error
│   
└── duplicateDetailInfo&lt;span class="o"&gt;()&lt;/span&gt;
     └── &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;? &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; handling error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the previous &lt;code&gt;try-catch&lt;/code&gt; case shown earlier, it is difficult to identify control flow because it was not easy to determine where exceptions is handled in the case of overlapping email and phone.  On the other hand, for the &lt;code&gt;if-else&lt;/code&gt; approach, the control flow is intuitively processed according to the return value of function, so it is easy to find out what logic runs next and where the error occurs.&lt;/p&gt;

&lt;p&gt;Of course, this approach also has the disadvantage of having to branch out with if statements for every case that occurs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I looked up a lot of materials about control flow and found that using &lt;code&gt;try-catch&lt;/code&gt; was considered an anti-pattern because it is difficult to identify the flow of code. Therefore, I believe that the best way is to treat the control flow as an intuitive &lt;code&gt;if-else&lt;/code&gt; approach according to the return value, even if the amount of code is large, rather than a &lt;code&gt;try-catch&lt;/code&gt; approach where the code is concise but unclear where an exception is handled.&lt;/p&gt;

&lt;p&gt;If you want to get further details about why &lt;code&gt;try-catch&lt;/code&gt; exception handling is an anti-pattern, I recommend you refer to &lt;a href="https://softwareengineering.stackexchange.com/q/189222"&gt;this post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This article is originally published by myself &lt;a href="https://dzone.com/articles/control-flow-try-catch-or-if-else"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>performance</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>The Best Way To Migrate a RabbitMQ Server</title>
      <dc:creator>Juhee Kang</dc:creator>
      <pubDate>Sat, 03 Apr 2021 03:16:37 +0000</pubDate>
      <link>https://dev.to/claudiajkang/the-best-way-to-migrate-a-rabbitmq-server-466o</link>
      <guid>https://dev.to/claudiajkang/the-best-way-to-migrate-a-rabbitmq-server-466o</guid>
      <description>&lt;p&gt;Instead of repetitive tasks, I discovered a relationship between RabbitMQ settings and a hostname, which ultimately decreased repetition when migrating servers.&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;As the userbase of my company increased over time, I realized it was necessary to apply auto-scaling to my servers. It required server migration. Migrating RabbitMQ settings meant a lot of repetitive tasks to ensure a smooth migration process; rather than perform this, I discovered a relationship between the RabbitMQ settings and the hostname, which ultimately decreased repetition.&lt;/p&gt;

&lt;p&gt;In this article, I'll explain how to migrate RabbitMQ using the hostname.&lt;/p&gt;

&lt;h1&gt;
  
  
  A Basic Way To Migrate RabbitMQ (Using rabbitmqctl)
&lt;/h1&gt;

&lt;p&gt;In order to migrate RabbitMQ to the same existing server setting, you need to manually set each of the settings (such as vhost, username, permission, etc.) from the existing server. For example, there is a RabbitMQ server consisted of the settings which the Vhost is test and username is Claudia. If you migrate this server, you will go through the following steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check the Existing Server RabbitMQ Setting
&lt;/h3&gt;

&lt;p&gt;1) Check the vhost&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;rabbitmqctl list_vhosts
Listing vhosts ...
name
/
&lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Check the username&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;rabbitmqctl list_users 
Listing &lt;span class="nb"&gt;users&lt;/span&gt; ... 
user tags 
claudia &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; 
guest &lt;span class="o"&gt;[&lt;/span&gt;administrator]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Try To Migrate To the RabbitMQ Server
&lt;/h3&gt;

&lt;p&gt;1) Install the RabbitMQ server on a new server&lt;br&gt;
2) Create a vhost using &lt;code&gt;rabbitmqctl&lt;/code&gt; on the new server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;rabbitmqctl add_vhost &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Create a user using &lt;code&gt;rabbitmqctl&lt;/code&gt; on the new server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;rabbitmqctl add_user claudia claudia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Set user permission using &lt;code&gt;rabbitmqctl&lt;/code&gt; on the new server&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;rabbitmqctl set_user_tags claudia administrator 
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;rabbitmqctl set_permissions &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nb"&gt;test &lt;/span&gt;claudia &lt;span class="s2"&gt;".*"&lt;/span&gt; &lt;span class="s2"&gt;".*"&lt;/span&gt; &lt;span class="s2"&gt;".*"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is easy to migrate the RabbitMQ server using this way when the server has some vhost, user, etc… But if the server has many settings, it is inefficient to migrate this way because it will take a lot of time. (Maybe it requires repetition according to the settings.)&lt;/p&gt;

&lt;p&gt;Therefore, I will introduce a new migration way without repetition that works.&lt;/p&gt;

&lt;h1&gt;
  
  
  A New Way To Migrate RabbitMQ Using Copy and Setting Hostname
&lt;/h1&gt;

&lt;p&gt;For using the new way, we need to check the setting files. You can find the setting files on &lt;code&gt;/var/lib/rabbitmq&lt;/code&gt;. Thus, let's start a migration using these files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check the Existing Server RabbitMQ Setting
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;rabbitmqctl list_vhosts
Listing vhosts ...
name
/
&lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;rabbitmqctl list_users
Listing &lt;span class="nb"&gt;users&lt;/span&gt; ...
user tags
claudia &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
guest &lt;span class="o"&gt;[&lt;/span&gt;administrator]
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;hostname
&lt;/span&gt;claudia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Try To Migrate the RabbitMQ Server
&lt;/h3&gt;

&lt;p&gt;1) Find the setting files on the existing server&lt;br&gt;
You can find the setting files according to the following command. (Tip: the path of RabbitMQ setting files is &lt;code&gt;/var/lib/rabbitmq&lt;/code&gt;.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /var/lib/rabbitmq/
mnesia
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /var/lib/rabbitmq/mnesia/
root@claudia:/var/lib/rabbitmq/mnesia# &lt;span class="nb"&gt;ls
&lt;/span&gt;rabbit@claudia rabbit@claudia-feature_flags
rabbit@claudia.pid rabbit@claudia-plugins-expand
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Install the RabbitMQ server on a new server.&lt;/p&gt;

&lt;p&gt;3) Copy the setting file of the existing server to &lt;code&gt;/var/lib/rabbitmq/mnesia&lt;/code&gt; on the new server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;scp &lt;span class="nt"&gt;-r&lt;/span&gt; /var/lib/rabbitmq/mnesia &amp;lt;new-server-ip&amp;gt;:/var/lib/rabbitmq/mnesia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4) Change the hostname&lt;br&gt;
If the hostname is not equal to the past one, the new server will not work properly.&lt;/p&gt;

&lt;p&gt;If the hostname is not equal to the past one, the new server will not work properly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;hostnamectl set-hostname claudia 
&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;hostname 
&lt;/span&gt;claudia
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5) Restart the RabbitMQ server&lt;br&gt;
&lt;code&gt;$ sudo systemctl restart rabbitmq-server&lt;/code&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Check the RabbitMQ Setting on the New Server
&lt;/h1&gt;

&lt;p&gt;You can see that the migration is completed successfully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;rabbitmqctl list_vhosts
Listing vhosts ...
name
/
&lt;span class="nb"&gt;test&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;rabbitmqctl list_users
Listing &lt;span class="nb"&gt;users&lt;/span&gt; ...
user tags
claudia &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
guest &lt;span class="o"&gt;[&lt;/span&gt;administrator]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this method, no matter how many settings you have, it is easy to complete the migration.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Is This Possible?
&lt;/h1&gt;

&lt;p&gt;When starting the RabbitMQ server, it reads the environment files from the base directory according to &lt;code&gt;rabbitMQ_NODENAME&lt;/code&gt;. Let's check the initialization environment process of the &lt;a href="https://github.com/rabbitmq/rabbitmq-server/blob/561d2e660decb29a2b86c52e72137865542a51fb/deps/rabbit_common/src/rabbit_env.erl"&gt;rabbitmq-server code&lt;/a&gt;, which is a function(&lt;code&gt;get_prefixed_env_var&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/rabbitmq/rabbitmq-server/blob/561d2e660decb29a2b86c52e72137865542a51fb/deps/rabbit_common/src/rabbit_env.erl#L464-L473"&gt;rabbit_env.erl#L464–473&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erlang"&gt;&lt;code&gt;&lt;span class="c"&gt;%% -------------------------------------------------------------------
%%
%% RABBITMQ_NODENAME
%%   Erlang node name.
%%   Default: rabbit@
%%
%% RABBITMQ_USE_LONGNAME
%%   Flag indicating if long Erlang node names should be used instead
%%   of short ones.
%%   Default: unset (use short names)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/rabbitmq/rabbitmq-server/blob/561d2e660decb29a2b86c52e72137865542a51fb/deps/rabbit_common/src/rabbit_env.erl#L744-L836"&gt;rabbit_env.erl#L744-L836&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight erlang"&gt;&lt;code&gt;&lt;span class="c"&gt;%% -------------------------------------------------------------------
%%
%% RABBITMQ_MNESIA_BASE
%%   Directory where to create Mnesia directory.
%%   Default: (Unix) ${SYS_PREFIX}/var/lib/rabbitmq/mnesia
%%         (Windows) ${RABBITMQ_BASE}/db
%%
%% RABBITMQ_MNESIA_DIR
%%   Directory where to put Mnesia data.
%%   Default: (Unix) ${RABBITMQ_MNESIA_BASE}/${RABBITMQ_NODENAME}
%%         (Windows) ${RABBITMQ_MNESIA_BASE}\${RABBITMQ_NODENAME}-mnesia
&lt;/span&gt;
&lt;span class="nf"&gt;mnesia_base_dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;from_remote_node&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;Remote&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nf"&gt;get_prefixed_env_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RABBITMQ_MNESIA_BASE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="n"&gt;false&lt;/span&gt; &lt;span class="k"&gt;when&lt;/span&gt; &lt;span class="nv"&gt;Remote&lt;/span&gt; &lt;span class="o"&gt;=:=&lt;/span&gt; &lt;span class="n"&gt;offline&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;update_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mnesia_base_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;false&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nf"&gt;mnesia_base_dir_from_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nv"&gt;Dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;normalize_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nf"&gt;update_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mnesia_base_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nf"&gt;mnesia_base_dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="nf"&gt;mnesia_base_dir_from_env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;


&lt;span class="nf"&gt;mnesia_base_dir_from_env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nf"&gt;get_prefixed_env_var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"RABBITMQ_MNESIA_BASE"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;
        &lt;span class="n"&gt;false&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nv"&gt;Dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_default_mnesia_base_dir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nf"&gt;update_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mnesia_base_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;Value&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="nv"&gt;Dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;normalize_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nf"&gt;update_context&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mnesia_base_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that if you copy the existing setup file format to the base directory &lt;code&gt;/var/lib/RabbitMQ/mnesia&lt;/code&gt;, the setup will be applied as it is. In addition, you can see this type of setup files such as &lt;code&gt;rabbit@&amp;lt;hostname&amp;gt;-&amp;lt;option&amp;gt;&lt;/code&gt; because of the default value of &lt;code&gt;RabbitMQ_NODENAME(rabbit@&amp;lt;hostname&amp;gt;)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Therefore, if you have a hostname that is not the same as the existing server, the server will not run normally.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;There are many different ways to migrate RabbitMQ, but it is difficult to find a way to do it easily and quickly. If you need to migrate RabbitMQ with complex settings, I recommend you use this hostname and the setup file copy method. Maybe using hostname makes for a more easy time to migrate RabbitMQ.&lt;/p&gt;

&lt;p&gt;This article is originally published by myself &lt;a href="https://dzone.com/articles/the-best-way-to-migration-rabbitmq"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
    </item>
  </channel>
</rss>
