<?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: Hello Web!</title>
    <description>The latest articles on DEV Community by Hello Web! (@geny).</description>
    <link>https://dev.to/geny</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%2F1505614%2F7a0f7391-6908-40cc-86f1-38147005cffa.png</url>
      <title>DEV Community: Hello Web!</title>
      <link>https://dev.to/geny</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/geny"/>
    <language>en</language>
    <item>
      <title>מה זה Authenticated Origin Pulls ואיך זה מגן על האתר שלי</title>
      <dc:creator>Hello Web!</dc:creator>
      <pubDate>Wed, 31 Jul 2024 07:18:42 +0000</pubDate>
      <link>https://dev.to/geny/mh-zh-authenticated-origin-pulls-vyk-zh-mgn-l-htr-shly-44m6</link>
      <guid>https://dev.to/geny/mh-zh-authenticated-origin-pulls-vyk-zh-mgn-l-htr-shly-44m6</guid>
      <description>&lt;p&gt;‫Cloudflare היא חברת אינטרנט ענקית, ש-20% מהאינטרנט "עובר דרכה". הם הפכו פופולריים במיוחד מכיוון שהם מספקים שירותים חינמיים שבדרך כלל עלו אלפי דולרים. הכוונה כמובן להגנה מהתקפות מבוזרות על האתרים שלכם, וגם איחסון (cache) קבצים סטאטיים על השרתים שלהם, שמורידים את העומס על האתר שלכם. מי לא ירצה, ובחינם?&lt;/p&gt;

&lt;p&gt;‫הם מסבירים את היכולות להציע את השירותים האלה בחינם, מאחר שהם כבר פתרו את הבעיות האלה ללקוחות הגדולים והכבדים שלהם, ולהוסיף עוד אתר על הדרך, לא עולה להם הרבה. כנל לגבי הקאש, משהו בסגנון של, להקים דאטאסנטר עולה כמה מליונים, ואחרי זה לא עולה כלום. מאחר שכבר יש להם את התשתית, להוסיף לקוחות אחרים לא פוגע בהם הרבה. היו מספר מקרים שלקוחות חויבו לעבור לתוכניות אנטרפרייס בעלות מתאימה לשם, אבל בנתיים הרוב המוחלט של הלקוחות מרוצים.&lt;/p&gt;

&lt;p&gt;‫ב2019 החברה הונפקה אז ייתכן שהלחץ להרוויח יגדל עם הזמן, אבל בכל מקרה, לא על זה רציתי לדבר איתכם היום...&lt;/p&gt;

&lt;p&gt;‫Cloudflare מגינה על האתר שלכם על ידי כך שכל התקשורת עוברת דרכם, והלקוחות קצה לא מדברים ישירות עם הIP של האתר שלכם. לכן יש חשיבות למנוע ממי שלא צריך, לדעת מה הכתובת IP האמיתית של האתר שלכם. הבעיה היא שהיום להריץ חיפוש על כל כתובות הIP שיש זה כבר לא מדע בדיוני, ורוב הסיכויים שכבר עכשיו כל כמה שניות מישהו מנסה להתחבר לשרת שלכם, בשיטת מצליח. בפרויקט שלנו, &lt;a href="https://il.ferom.app" rel="noopener noreferrer"&gt;אתר הכרויות,&lt;/a&gt; אבטחה האתר המידע של הלקוחות היא בחשיבות עליונה, לכן אנו תמיד עוקבים אחר הפתרונות שהספקים ממליצים ליישם.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;‫הגישה הנאיבית - לחסום את כל מי שלא מ Cloudflare&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;‫זאת אופציה דיי פופולרית, וניתן לקבל את כל הכתובות של CF כאן: &lt;code&gt;https://www.cloudflare.com/ips&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;‫אפשר לעשות את החסימה ברמת הלינוקס דרך iptables או ufw, או ברמת הפרוקסי (nginx), אבל עדיף להשתמש בחומת אש שהיום כל שירות ענן מציע ולחסוך מהשרת שלכם עבודה מיותרת.&lt;/p&gt;

&lt;p&gt;‫הפתרון הזה אומנם יאפשר רק לרשת של CF לגשת לאתר שלכם, אבל יש איתו בעיה.&lt;/p&gt;

&lt;p&gt;‫מאחר שבעצם כל אחד יכול להרשם ולהשתמש בשירותים של CF. שום דבר לא ימנע ממישהו לכוון את הדומיין שהוא קנה לIP מסוים דרך CF, אפילו אם זה IP לא שלו, ולראות האם יש תגובה. וגם יש את שאר השירותים הנוספים, כמו workers, tunnels וכו', כולם יראו לאתר שלכם כאילו הם באים מהרשת הפנימית של CF.&lt;/p&gt;

&lt;p&gt;‫לכן כדאי בנוסף להגדיר שהאתר שלכם לא יגיב אם ה&lt;code&gt;Host&lt;/code&gt; לא תואם לאתר שלכם, או למשל לבדוק האם יש את הההאדר של &lt;code&gt;cf-worker&lt;/code&gt; וכו'.&lt;/p&gt;

&lt;p&gt;‫אבל יש פתרון יותר טוב.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;‫Authenticated Origin Pulls - מה זה&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;‫הפיצר הזה מאפשר לנו בעזרת mTLS לוודא שאנחנו מדברים עם ה"חשבון" שלנו ברשת הפנימית של CF.&lt;/p&gt;

&lt;p&gt;‫כולנו כבר מכירים TLS, הפרוטוקול הצפנה שמאבטח את האתרים של כולנו, נותן את אייקון המנעול. ומאפשר לנו לוודא שאנחנו מדברים עם האתר הנכון.&lt;/p&gt;

&lt;p&gt;‫mTLS מוסיף שלב נוסף, בדיקה נוספת, בשביל לוודא גם את הצד השני.&lt;/p&gt;

&lt;p&gt;‫זאת אומרת שצריך זוג מפתחות נוסף - פרטי ופומבי, את הפומבי במקרה הזה אנחנו משאירים לנו, ואת הפרטי נותנים לCF. המפתח יכול להיות משויך ברמת Hostname ספציפי, או לכל הZONE של הדומיין שלנו.&lt;/p&gt;

&lt;p&gt;‫ככה אם מישהו חיצוני ינסה לתקשר ישירות עם הIP שלנו, בלי קשר אם הוא מהרשת הפנימית או לא, הוא לא יצליח להוכיח את הזהות שלו.&lt;/p&gt;

&lt;p&gt;‫החסרון היחיד כרגע הוא שאין אפשרות להפעיל את האפשרות הזאת דרך הממשק באתר, וצריך לבצע מספר בקשות דרך הAPI.&lt;/p&gt;

&lt;p&gt;‫בנוסף הCertificate צריך להיות חתום עם CA - אפשרי CA שיצרנו לבד.&lt;/p&gt;

&lt;p&gt;‫עם זאת, השיטה הזאת סוגרת את כל הפינות, וגם מקלה על התחזוקה מאחר שלא צריך לעקוב אחר שינויים ברשימת הIP של CF. להגנה מלאה ניתן לשלב גם את החסימות הקודמות.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Почта на своем домене – выбор провайдеров для малого бизнеса</title>
      <dc:creator>Hello Web!</dc:creator>
      <pubDate>Wed, 29 May 2024 14:19:38 +0000</pubDate>
      <link>https://dev.to/geny/pochta-na-svoiem-domienie-vybor-provaidierov-dlia-malogho-bizniesa-17la</link>
      <guid>https://dev.to/geny/pochta-na-svoiem-domienie-vybor-provaidierov-dlia-malogho-bizniesa-17la</guid>
      <description>&lt;p&gt;Одним из важных аспектов присутствия в Интернете является ваш адрес электронной почты. Собственный домен электронной почты не только добавляет элегантности вашему общению, но и помогает завоевать доверие ваших клиентов и заказчиков.&lt;/p&gt;

&lt;p&gt;Получать электронную почту может быть легко, вам следует выбирать своего провайдера в зависимости от того, как часто вам нужно отвечать или отправлять исходящие электронные письма, а также от количества людей, которые будут иметь доступ к вашей корпоративной электронной почте.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;strong&gt;Cloudflare&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Cloudflare — компания, занимающаяся производительностью и безопасностью веб-сайтов, которая предоставляет набор продуктов и услуг, помогающих предприятиям и частным лицам повысить скорость, безопасность и надежность своих веб-сайтов и приложений. Cloudflare, основанная в 2009 году, стала одной из самых популярных сетей доставки контента (CDN) в мире.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Стоимость&lt;/strong&gt;: бесплатно.&lt;/p&gt;

&lt;p&gt;Вы можете легко настроить маршрутизацию электронной почты, чтобы перехватывать любую входящую электронную почту и перенаправлять ее на вашу личную электронную почту.&lt;/p&gt;

&lt;p&gt;С исходящими электронными письмами все сложнее. Вы можете отправлять электронные письма бесплатно через партнерство MailChannels, но это требует некоторых навыков программирования и больше предназначено для транзакционных писем.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. AWS SES
&lt;/h2&gt;

&lt;p&gt;Amazon Web Services (AWS) — это комплексная платформа облачных вычислений, предоставляемая Amazon. AWS предлагает широкий спектр услуг, включая вычислительную мощность, хранилище, базы данных, аналитику, машинное обучение и многое другое.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Стоимость&lt;/strong&gt;:&lt;br&gt;
Исходящие электронные письма 0,10$ за 1000 писем.&lt;br&gt;
Входящие электронные письма 0,10$ за 1000 писем.&lt;/p&gt;

&lt;p&gt;В течение первого года до 3000 писем в месяц бесплатны. В любом случае, настройка SES требует значительных технических навыков, и вероятность того, что ваше письмо попадет в спам, очень высока. Рекомендуется только в том случае, если вы уже планируете использовать AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. iCloud Mail
&lt;/h2&gt;

&lt;p&gt;iCloud от Apple — это облачное хранилище и служба облачных вычислений, предоставляемая Apple Inc., которая позволяет пользователям хранить и получать доступ к своим данным, включая файлы, фотографии, музыку и многое другое, с любого устройства, подключенного к Интернету.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Стоимость&lt;/strong&gt;: 1$/месяц.&lt;/p&gt;

&lt;p&gt;Чтобы использовать собственный домен с iCloud, вам необходимо иметь iCloud+, цены меняются в зависимости от региона. Можно добавить до 5 пользователей. Оплата На данный момент недоступна в России.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Zoho
&lt;/h2&gt;

&lt;p&gt;Компания-разработчик программного обеспечения, предлагающая набор бизнес-приложений для различных отраслей. Компания была основана в 1996 году и с тех пор стала одним из ведущих поставщиков облачных бизнес-решений, популярных в Азии и Африке.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Стоимость&lt;/strong&gt;: бесплатно, 1 домен, до 5 пользователей.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Google Workspace
&lt;/h2&gt;

&lt;p&gt;Набор облачных программных решений для повышения производительности, разработанный Google. Он предлагает ряд инструментов, призванных помочь отдельным лицам и организациям сотрудничать, общаться и работать более эффективно.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Стоимость&lt;/strong&gt;: $6/месяц.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Microsoft 365 Business
&lt;/h2&gt;

&lt;p&gt;Облачный пакет программного обеспечения для повышения производительности, разработанный Microsoft. Он объединяет функциональность решений Office 365, Windows 10 Enterprise и Enterprise Security &amp;amp; Mobility в один интегрированный пакет. Эта комплексная платформа призвана предоставить предприятиям надежный набор инструментов для улучшения совместной работы, безопасности и производительности.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Стоимость&lt;/strong&gt;: $6/месяц.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. VK WorkSpace (Mail.ru для бизнеса)
&lt;/h2&gt;

&lt;p&gt;Коммуникационная платформа для бизнеса. Включает корпоративную почту с календарём, мессенджер с аудио- и видеозвонками, облачное хранилище со встроенным редактором документов.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Стоимость&lt;/strong&gt;: 199 ₽/месяц.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Яндекс 360
&lt;/h2&gt;

&lt;p&gt;Виртуальное рабочее пространство, которое включает в себя ваши персональные сервисы: Почту, Диск, Телемост, Документы, Календарь и Заметки.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Стоимость&lt;/strong&gt;: 249 ₽/месяц.&lt;/p&gt;

&lt;h2&gt;
  
  
  О проекте
&lt;/h2&gt;

&lt;p&gt;Пока другие сервисы прекратили свою работу, мы решили запустить новый &lt;a href="https://ru.ferom.app"&gt;сайт знакомств&lt;/a&gt;. Как и в любом бизнесе, перед нами встал вопрос, какой провайдер почтового хостинга выбрать. Только взвесив различные варианты, мы смогли принять решение, соответствующее нашим потребностям. Надеемся, наш пост помог вам сделать то же самое!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>JavaScript Promises: Explaining then &amp; catch to a 5 year old.</title>
      <dc:creator>Hello Web!</dc:creator>
      <pubDate>Sun, 26 May 2024 01:31:28 +0000</pubDate>
      <link>https://dev.to/geny/javascript-promises-explaining-then-catch-to-a-5-year-old-3agc</link>
      <guid>https://dev.to/geny/javascript-promises-explaining-then-catch-to-a-5-year-old-3agc</guid>
      <description>&lt;h2&gt;
  
  
  1. Promise.catch() is not try{}...catch(){}.
&lt;/h2&gt;

&lt;p&gt;The .catch() method of promise is just .then(void 0, onRejected). It may seem like it "catches" some errors, but that is just because of the special handling of .then() logic.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Promise.then()
&lt;/h2&gt;

&lt;p&gt;A confusing quirk of .then(onFulfilled, onRejected), is if &lt;strong&gt;EITHER&lt;/strong&gt; of the callbacks throw an error, it's promise will be rejected with the error. For example:&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;promise&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;// onFulfilled&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;// onRejected&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;oops rejected&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&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="c1"&gt;// aka .catch&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;caught&lt;/span&gt;&lt;span class="dl"&gt;'&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="c1"&gt;// caught Error: oops rejected&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;promise&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;// onFulfilled&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;oops fulfilled&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="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;// onRejected&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&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="c1"&gt;// aka .catch&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;caught&lt;/span&gt;&lt;span class="dl"&gt;'&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="c1"&gt;// caught Error: oops fulfilled&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In both cases, the error will be &lt;strong&gt;caught by the first then()&lt;/strong&gt;, and passed as a rejection to the 2nd (our catch-then).&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Chaining: Unless your then() callback returns a Promise, it will be immediately resolved.
&lt;/h2&gt;

&lt;p&gt;When you chain promises&lt;/p&gt;

&lt;p&gt;promise.then(cb1).then(cb2)...&lt;/p&gt;

&lt;p&gt;if cb1 returns a promise, cb2 will wait for it. if cb1 returns any other object (or nothing), it will be immediately resolved.&lt;/p&gt;

&lt;p&gt;if cb1 errors out, it will be caught by then() logic, and passed to the onRejected of the 2nd then(). If we don't specify one, the &lt;strong&gt;default onRejected&lt;/strong&gt; will be used: which just throws an error. Which will be caught again by then(), and passed further down. Example:&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;promise&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boom&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;// we never get here, default onRejected will be called, throw an error, catch it, and pass it further down&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;// we never get here, default onRejected will be called, throw an error, catch it, and pass it further down&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;// we never get here, default onRejected will be called, throw an error, catch it, and pass it further down&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="c1"&gt;// we never get here, default onRejected will be called, throw an error, catch it, and pass it further down&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;caught&lt;/span&gt;&lt;span class="dl"&gt;'&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="c1"&gt;// caught Error: boom&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be aware this catching mechanic is special to then(), for example this won't work:&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;wont-work&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;promise&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;caught&lt;/span&gt;&lt;span class="dl"&gt;'&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="c1"&gt;// Uncaught Error: wont-work&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To illustrate, if we use a &lt;strong&gt;custom onRejected&lt;/strong&gt;, and do not throw an error, we can recover the chain (which may, or may not be, what you want)&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;promise&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boom&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;

    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="kd"&gt;function&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;interesting, we caught an error&lt;/span&gt;&lt;span class="dl"&gt;'&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="c1"&gt;// since we don't throw a new one, the chain will recover&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;recover&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="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;caught&lt;/span&gt;&lt;span class="dl"&gt;'&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="c1"&gt;// interesting, we caught an error Error: boom&lt;/span&gt;
&lt;span class="c1"&gt;// recover&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
