19,785 Matching Annotations
  1. Feb 2022
    1. alias_method :normalize_whitespace_with_warning, :normalize_whitespace def normalize_whitespace(*args) silence_warnings do normalize_whitespace_with_warning(*args) end end

      suppress warnings

    1. Since factory_bot_rails automatically loads factory definitions as your application loads, writing a definition like this would cause another Daniel to get added to your database every time you start the server or open a console. I like Daniels and all, but there is a limit.
    1. As a workaround, you can use setters in every affected reactive block instead of direct assignment. let localForm = {}; const setLocalForm = (data) => { localForm = data; }; $: setLocalForm({...$formData});
    1. At this point I would call into question the job of Event to both be responsible for managing what gets charged and how something should be charged. I would probably investigate moving those to external service classes to keep charging responsibilities out of a simple event object.
    1. however, I prefer to take it as an indication that a pretty smart group of people didn't think there was a particularly strong reason to use a different term.

      seems reasonable

    2. Unfortunately, I think a lot of the answers here are perpetuating or advancing the idea that there's some complex, meaningful difference. Really - there isn't all that much to it, just different words for the same thing.
    3. 'method' is the object-oriented word for 'function'. That's pretty much all there is to it (ie., no real difference).
    4. a function is a mathematical construct. I would say all methods are functions but not all functions are methods

      theory

    5. Coming from a functional programming background, I feel there is a profound distinction between function and method. Mainly methods have side effects, and that functions should be pure thus giving a rather nice property of referential transparency
    6. I agree it might be nice if "function" and "method" meant what you wanted them to, but your definitions do not reflect some very common uses of those terms.
  2. Jan 2022
    1. Ruby 2.6 introduces an initial implementation of a JIT (Just-In-Time) compiler. The JIT compiler aims to improve the performance of Ruby programs. Unlike traditional JIT compilers which operate in-process, Ruby’s JIT compiler writes out C code to disk and spawns a common C compiler to generate native code. For more details about it, see the MJIT organization by Vladimir Makarov.
    1. For example, if you pre-build a swordman, a spearman and an horseman in 4 cities, you can produce a total of 12 units in 3 turns. This make you save a lot of gold in units maintenance for a good amount of turns.
    1. I just didn't realize the harbor needed to be in the capital as well since it says that it creates a city connection with the capital, and doesn't mention that your capital needs one too. I just figured I could get away without one
    1. tr '\n' '\\n' would change newlines to backslashes (and then there's an extra n in the second set). sed 's/\n/\\n/g won't work because sed doesn't load the line-terminating newline into the buffer, but handles it internally.
    1. This proposal is deeply flawed and would have far-reaching consequences if implemented. In #31148 I proposed a strategy to address the same pain points in a correct, more generic way. Regardless of whether my approach is taken or not, async handling of promises is a core feature that simply cannot be deprecated, and we should remove the erroneous deprecation accordingly.
    2. NODE_OPTIONS=--unhandled-rejections=none node
    1. There are other pjax implementations floating around, but most of them are jQuery-based or overengineered. Hence simple-pjax.
    1. As said in the chapter, there’s an "implicit try..catch" around the function code. So all synchronous errors are handled. But here the error is generated not while the executor is running, but later. So the promise can’t handle it.
    2. new Promise(function(resolve, reject) { setTimeout(() => { throw new Error("Whoops!"); }, 1000); }).catch(alert);
    3. we should have the unhandledrejection event handler (for browsers, and analogs for other environments) to track unhandled errors and inform the user (and probably our server) about them, so that our app never “just dies”.
    4. What happens when a regular error occurs and is not caught by try..catch? The script dies with a message in the console. A similar thing happens with unhandled promise rejections.
    1. You cannot try/catch the reactive statement ($: has no effect outside of the top-level) window.onerror does not catch it window.onunhandledrejection does not catch it

      .

    2. The best you can do is try/catch inside a function that is reactively called, but my goal is to have a global exception handler to handle all exceptions that I did not expect...
    1. It's vanilla JS, doesn't bind you to specifc syntax and that's the main reason why I like svelte that it doesn't try to sandbox you into framework constraints.
    2. const originalUnhandledRejection = window.onunhandledrejection; window.onunhandledrejection = (e) => { console.log('we got exception, but the app has crashed', e); // or do Sentry.captureException(e); originalUnhandledRejection(e); }
    3. If at least one component has smallest unhandled error, the whole app will crash and users will not know what to do and developers will not know such an error occurred.
    4. When an error is thrown inside a Promise it looks like Firefox still calls window.onerror, but Chrome swallows the error silently.
    5. Maybe once the core onError lifecycle is implemented (if maintainers decide to go that way) everyone will discover you're right and an implementation will be built in. I think that's probably what's going to happen. But until real life has proved it, it's usually best to go for the smallest most broadly applicable solution. I can definitely imagine <svelte:error> eventually being a thing, but it's a pretty dramatic change compared to an added importable function.
    6. Having a consistent and predictable pattern is key to the elegance.
    7. I think the issue is that it's not totally perfect. It doesn't define what should happen in parent components, it's not as flexible as onError and it doesn't allow you (for instance) to nest a svelte:head inside, or decide what to do with the rest of the rendering. What do you do with <div>My component</div> in your example? What about changing the <title>? I assume you can inspect the error...does <svelte:error> allow specifying which error types to expect?
    8. That's like the example i wrote, and i think it's very ugly. It's annoying when frameworks are very elegant in demos and presentations but then that elegance disappear when you have to write real world code.
    9. An annoying thing about frameworks is when they get too opinonated, which is, in my view, a problem React has.
    10. const unsubscribe = errorStore.subscribe(value => { if (!value) { return } error = value errorStore.set() })
    11. Boilerplate is only boilerplate if it's the same everywhere, which it shouldn't be.
    12. Additionally, if you're writing a notification display in every single component, wrapped in a <svelte:error> tag, that's the very definition of boilerplate.

      In other words, adding a svelte:error tag wouldn't help much.

    13. and if I think this is too boilerplatey, I can export a handler from some .js file and pass the error to that: <script> import { onError } from 'svelte' import { genericHandler } from '../my-error-handler.js' onError(genericHandler(e => { // code which is called first to try to handle this locally return true // we've handled it here, don't do anything else. }) </script>
    14. If a developer wants to handle the error inside the component and also wants to have it bubble up, they can use this.fire('error', e) within onerror.
    1. So it is safe to use an async function as the callback argument to setTimer and setInterval. You just need toBe sure to wrap any operations that can throw an exception in a try/catch block andBe aware that the timer will not await on the promise returned by your async function
    2. My gut told me calling an async function from the setTimeout callback was a bad thing. Since the setTimeout machinery ignores the return value of the function, there is no way it was awaiting on it. This means that there will be an unhandled promise. An unhandled promise could mean problems if the function called in the callback takes a long time to complete or throws an error.
    3. The callback executed by setTimeout is not expected to return anything, it just ignores the returned value. Since once you enter the promise/async world in JavaScript you cannot escape, I was left to wonder what happens when the setTimeout callback returns a promise?
    1. test2 being marked async does wrap your return value in a new promise:
    2. const rejectedP = Promise.reject('-'); const finallyP = rejectedP.finally(); const result1 = rejectedP; const result2 = new Promise(resolve => { const rejectedP = Promise.reject('-'); const finallyP = rejectedP.finally(); resolve(rejectedP); }); we can see that the first snippet creates two promises (result1 and rejectedP being the same) while the second snippet creates three promises. All of these promises are rejected, but the rejectedP rejection is handled by the callbacks attached to it, both through ….finally() and resolve(…) (which internally does ….then(resolve, reject)). finallyP is the promise whose rejection is not handled in the both examples. In the second example, result2 is a promise distinct from rejectedP that is also not handled, causing the second event.
    1. You basically did var a = promise.then(…); var b = promise.catch(…); creating a branch in the chain. If promise is getting rejected now, the catch callback will be called and b will be a fulfilled promise just fine, but the a promise is getting rejected too and nobody handles that. Instead, you should use both arguments of then and write Requirement.create({id: id, data: req.body.data, deleted: false}) .then(requirement => { res.json(requirement); }, reason => { let err = {'error': reason}; res.json(err); });
    1. Updates/edits based on comments should preferably be reflected in the question itself. This way other readers don't have to weed out the whole comment section. You find the edit option under the question.
    1. Just "ignoring" a Promise result if it is not longer needed is an antipattern in my opinion.
    2. Moving forward I'd rather see {#await} being removed than adding more {#await}. But that's just from my experience and I'm sure there are use-cases for it.
    3. I personally abstract everything away into stores. Stores are amazing. With everything I mean things like fetch, Worker or WebSocket.
    4. Another limitation is that you are forced into the syntax of the {#await} block. What I mean by that is that for example you can't add a loading class to a parent. You can only render stuff for the loading state in the given block. Nowhere else.
    5. export const fibonacci = function (n, initialData) { return readable( { loading: true, error: null, data: initialData, }, (set) => { let controller = new AbortController(); (async () => { try { let result = await fibonacciWorker.calculate(n, { signal: controller.signal }); set({ loading: false, error: null, data: result, }); } catch (err) { // Ignore AbortErrors, they're not unexpected but a feature. // In case of abortion we just keep the loading state because another request is on its way anyway. if (err.name !== 'AbortError') { set({ loading: false, error: err, data: initialData, }); } } })(); return () => { controller.abort(); }; } ); };
    6. <script> import { fibonacci } from './math.js'; $: result = fibonacci(n, 0); </script> <input type=number bind:value={n}> <p>The {n}th Fibonacci number is {$result.data}</p> {#if $result.loading} <p>Show a spinner, add class or whatever you need.</p> <p>You are not limited to the syntax of an #await block. You are free to do whatever you want.</p> {/if}
    7. Once you've written the imperative library/util code once, your components are super slim and completely reactive/declarative. Wow.
    8. Yes I love stores.
    9. No need to debounce fetch (terrible UX), just fire them away
    1. export const load: Load = async ({ page, session }) => { if (!isPublic(page.path) && !isAuthenticated(session)) { console.log('Unauthorized access to private page'); return { redirect: '/', status: 302 }; } else { console.log('Auth OK'); } return {}; };
    2. That whole setup works. If the user logs out, I can just write an empty JWT cookie and clear the $session.jwt value, redirect back to the home page, done.
    3. In hooks.js I have a handle function that basically does request.locals.jwt = cookies.jwt, and then a getSession function that returns { jwt: locals.jwt }
    1. Persisting across apps Your notifications can persist across multiple apps / page reloads, as long as they use this library. This is useful for a scenario where you show a notification and then redirect the browser to a different application, or trigger a full reload of the page. This is completely automatic and uses session storage.
    1. I have an idea: trigger a BSOD on unhandled promise rejection... just to teach users
    2. I invite even the most cantankerous among you to review it.
    3. To be perfectly frank, this proposal seems far more about creating the appearance of safety than addressing an actual deficit in application correctness. I'm not questioning the value in detecting unhandled promises (resolved OR rejected) as a development tool for calling attention to a potentially undesired flow... but just like other lint rules, this belongs in tooling and NOT the execution environment.
    4. Fundamentally, I think promise rejection is substantially different than "throwing" under normal synchronous flow.
    5. but has a critical difference: the expression console.log("before 2"); does not and cannot depend on the resolved value result. The throw propagates through all chained promises, and when it stops, there is no remaining undefined behavior! No piece of code is left in an unclear state, and therefore there is no reason to crash.
    6. If this proposal is fully implemented, we will end up with this garbage everywhere.
    7. I value this pattern because it allows concise concurrency.
    8. Node is entirely at liberty to limit the design the same way we crash the process on errors (which browsers do not).
    9. const promise = Promise.reject(new Error("Something happened!")); setTimeout(async () => { // You want to process the result here... try { const result = await promise; console.log(`Hello, ${result.toUpperCase()}`) } // ...and handle any error here. catch (err) { console.error("There was an error:", err.message); } }, 100);
  3. www.npmjs.com www.npmjs.com
    1. The yieldable objects currently supported are: promises thunks (functions) array (parallel execution) objects (parallel execution) generators (delegation) generator functions (delegation) Nested yieldable objects are supported, meaning you can nest promises within objects within arrays, and so on!
    2. co(function* () {  var result = yield Promise.resolve(true);  return result;}).then(function (value) {  console.log(value);}, function (err) {  console.error(err.stack);});
    3. It is a stepping stone towards ES7 async/await.
    4. Generator based control flow goodness for nodejs and the browser, using promises, letting you write non-blocking code in a nice-ish way.
    1. There are a lot of nasty gotchas with unhandled rejections. That's why Node.js gives you a mechanism for globally handling unhandled rejections.
    2. Seems easy, right? How about the below code, what will it print? new Promise((_, reject) => reject(new Error('woops'))). catch(error => { console.log('caught', err.message); }); It'll print out an unhandled rejection warning. Notice that err is not defined!
    3. Some argue that throwing an exception in the executor function is bad practice. I strongly disagree.
    1. Point being (again), definitions seem to differ, and what you call "full stack" is what I call "batteries-included framework". Full stack simply means (for me) that it gives you a way of building frontend and backend code, but implies nothing about what functionality is included in either part.
    2. Nothing in "full-stack" requires having a validation library in order for it to be full-stack, that would more be leaning towards the "batteries included" approach to a framework instead of strictly being about "full-stack".
    3. Yes, precisely because I've been involved in maintaining codebases built without real full stack frameworks is why I say what I said.The problem we have in this industry, is that somebody reads these blog posts, and the next day at work they ditch the "legacy rails" and starts rewriting the monolith in sveltekit/nextjs/whatever because that's what he/she has been told is the modern way to do full stack.No need to say those engineers will quit 1 year later after they realize the mess they've created with their lightweight and simple modern framework.I've seen this too many times already.It is not about gatekeeping. It is about engineers being humble and assume it is very likely that their code is very unlikely to be better tested, documented, cohesive and maintained than what you're given in the real full stack frameworks.Of course you can build anything even in assembler if you want. The question is if that's the most useful thing to do with your company's money.
    4. Tauri
    5. Vue+Vuetify was like writing binary by hand instead of using an expressive modern language that abstracts away 99% of plumbing.

      Vuetify

    6. It has many advantages but the main reason for me is that it simplifies your front end code. It's not perfect by any means, but overall its cons are worth it IMO.
    7. As someone who is a future-ex React developer who uses Svelte in a personal project

      "future-ex"

    1. but you want to style your components yourself and not be constrained by existing design systems like Material UI
    2. This is an unofficial, complete Svelte port of the Headless UI component library (https://headlessui.dev/)
    3. Instead of render props, we use Svelte's slot props: // React version <Listbox.Button> {({open, disabled} => /* Something using open and disabled */)} </Listbox.Button> <!--- Svelte version ---> <ListboxButton let:open let:disabled> <!--- Something using open and disabled ---> </ListboxButton>
    4. You want to use the commercial Tailwind UI component library (https://tailwindui.com/) in your Svelte project, and want a drop-in replacement for the React components which power Tailwind UI.
    1. Hi, it seems as though you have multiple questions: you should separate these into multiple posts.

      A multi-question post would be perfectly appropriate in a forum or mailing list. Seems a bit too strict to not allow something like this, where one has multiple related questions.

    2. SSR is used for pages as well, but prerendering means that rendering happens at build time instead of when a visitor visits the page.
    1. The most obvious time you'd encounter a 401 error, on the other hand, is when you have not logged in at all, or have provided the incorrect password.
    2. As mentioned in the previous article, the 403 error can result when a user has logged in but they don't have sufficient privileges to access the requested resource. For example, a generic user may be attempting to load an 'admin' route.
    1. The server generating a 401 response MUST send a WWW-Authenticate header field (Section 4.1) containing at least one challenge applicable to the target resource.

      Meaning that 99% of the people use it are using it "wrong" because they're not using it for HTTP authentication and don't send a WWW-Authenticate header field with their 401 response?

      Hmm. That's a tough one. On the one hand, the spec does say they must send it.

      Initial opinion

      But on the other hand, one could argue that that requirement only applies if using 401 for HTTP authentication. And that saying it's wrong to do so (as they claim at https://stackoverflow.com/questions/3297048/403-forbidden-vs-401-unauthorized-http-responses/14713094#14713094 and https://hyp.is/JA45zHotEeybDdM_In4frQ/stackoverflow.com/questions/3297048/403-forbidden-vs-401-unauthorized-http-responses) is having a too strict/narrow/literal interpretation.

      HTTP is meant to be used widely in many very different uses and contexts, most of which do not use this very specific HTTP authentication scheme; my opinion is that they shouldn't be denied from using it, just because they don't have anything useful WWW-Authenticate header field. (Or (which is also fine with me), just put something "emptyish" in the field, like "Unused". Unless that would trigger a Basic auth modal in the browser, in which case we shouldn't, for practical reasons.)

      Why shouldn't we be able to repurpose this same status code for uses that are still authentication, but just not HTTP authentication per se?

      Is it really wrong to repurpose this useful status code for other contexts, like cookie-based app-defined authentication systems?

      I say that it's okay to repurpose/reuse 401 for any authentication system (that uses HTTP as a part of it, even though not using HTTP's own authentication system), as long as we try to maintain the same semantic as originally intended/described here. I think it's okay to use 401 as a response to a XHR request, and then have the client redirect to a login page, which provides a way to authenticate again (reattempt the authentication challenge), analogous to how it works for HTTP authentication.

      Revised opinion

      https://stackoverflow.com/questions/3297048/403-forbidden-vs-401-unauthorized-http-responses/14713094#14713094 has made me change my mind and convinced me that...

      Authentication by schemes outside of (not defined by) RFC7235: Hypertext Transfer Protocol (HTTP/1.1): Authentication should not use HTTP status 401, because 401 Unauthorized is only defined (by current RFCs) by RFC7235: Hypertext Transfer Protocol (HTTP/1.1): Authentication, and has semantics and requirements (such as the requirement that "A server generating a 401 (Unauthorized) response MUST send a WWW-Authenticate header field containing at least one challenge.") that simply don't make sense or cannot be fulfilled if using a non-HTTP authentication scheme.

      403 Forbidden, on the other hand, is defined by the broader HTTP standard, in RFC7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content and RFC7235: Hypertext Transfer Protocol (HTTP/1.1): Authentication.

      In conclusion, if you have your own roll-your-own login process and never use HTTP Authentication, 403 is always the proper response and 401 should never be used.

      Couldn't a custom auth system use WWW-Authenticate header?

      The question was asked:

      Doesn't RFC7235 provide for "roll-your-own" or alternate auth challenges? Why can't my app's login flow present its challenge in the form of a WWW-Authenticate header? Even if a browser doesn't support it, my React app can...

      And I would say sure, if you want (and if the browser doesn't automatically show a Basic auth modal in this case and thwart your plans).

      They might be on to something here with that question!

      But that should probably be the test of whether you can/should use 401: are you actually using WWW-Authenticate header?

      Indeed I found an example where it is used for OAuth2.

    1. For example, suppose your API returns a 401 Unauthorized status code with an error description like The access token is expired. In this case, it gives information about the token itself to a potential attacker. The same happens when your API responds with a 403 Forbidden status code and reports the missing scope or privilege.
    2. An access token is expired, revoked, malformed, or invalid for other reasons.
    3. That comes in the form of the WWW-Authenticate header with the specific authentication scheme to use. For example, in the case of OAuth2, the response should look like the following:
    4. "The basic principle behind REST status code conventions is that a status code must make the client aware of what is going on and what the server expects the client to do next"
    5. You can fulfill this principle by giving answers to the following questions:Is there a problem or not?If there is a problem, on which side is it? On the client or on the server side?If there is a problem, what should the client do?
    6. Now, assume your client attempts to access a resource that it MUST NOT access at all, for example, because it belongs to another user. What status code should your API return? Should it return a 403 or a 401 status code?You may be tempted to return a 403 status code anyway. But, actually, you can't suggest any missing permission because that client has no way to access that resource. So, the 403 status code gives no actual helpful information. You may think that returning a 401 status code makes sense in this case. After all, the resource belongs to another user, so the request should come from a different user.However, since that resource shouldn't be reached by the current client, the best option is to hide it.
    7. Let's explore a different case now. Assume, for example, that your client sends a request to modify a document and provides a valid access token to the API. However, that token doesn't include or imply any permission or scope that allows the client to perform the desired action.In this case, your API should respond with a 403 Forbidden status code. With this status code, your API tells the client that the credentials it provided (e.g., the access token) are valid, but it needs appropriate privileges to perform the requested action.
    8. In the spirit of mutual collaboration between the client and the API, the response must include a hint on how to obtain such authorization.

      annotation meta: may need new tag: client/server cooperation?

    9. If the client request does not include any access token, demonstrating that it wasn't aware that the API is protected, the API's response should not include any other information.

      annotation meta: may need new tag: demonstrating....

    1. The difference is what the server expects the client to do next.
    2. Authentication by schemes outside of RFC2617 is not supported in HTTP status codes and are not considered when deciding whether to use 401 or 403.

      What does "are not considered when deciding whether to use 401 or 403" mean exactly? What exactly should not be considered, and what exactly should be considered instead? In other words, how did someone arrive at the conclusion that "if you have your own roll-your-own login process and never use HTTP Authentication, 403 is always the proper response and 401 should never be used."? Why is 403 okay to use for non-HTTP authentication, but not 401?

      Oh, I think I understand the difference now.

      They should have said:

      Authentication by schemes outside of (not defined by) RFC7235: Hypertext Transfer Protocol (HTTP/1.1): Authentication should not use HTTP status 401, because 401 Unauthorized is only defined (by current RFCs) by RFC7235: Hypertext Transfer Protocol (HTTP/1.1): Authentication, and has semantics and requirements (such as the requirement that "A server generating a 401 (Unauthorized) response MUST send a WWW-Authenticate header field containing at least one challenge.") that simply don't make sense or cannot be fulfilled if using a non-HTTP authentication scheme.

      403 Forbidden, on the other hand, is defined by the broader HTTP standard, in RFC7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content and RFC7235: Hypertext Transfer Protocol (HTTP/1.1): Authentication.

      In conclusion, if you have your own roll-your-own login process and never use HTTP Authentication, 403 is always the proper response and 401 should never be used.

      See also my comments in https://hyp.is/p1iCnnowEeyUPl9PxO8BuQ/www.rfc-editor.org/rfc/rfc7235

    3. Meaning if you have your own roll-your-own login process and never use HTTP Authentication, 403 is always the proper response and 401 should never be used.
    4. If HTTP authentication is not in use and the service has a cookie-based authentication scheme as is the norm nowadays, then a 403 or a 404 should be returned.
    5. While this seems to me like it's probably an accurate interpretation of the old RFC 2616, note that RFC 7231 defines the semantics of a 403 differently, and in fact explicitly states that "The client MAY repeat the request with new or different credentials."
    6. the meaning of the status code has been rewritten beneath our feet. (Annoyingly, the Changes from RFC 2616 appendix doesn't acknowledge the change!)
    7. it depends on the application but generally, if an authenticated user doesn't have sufficient rights on a resource, you might want to provide a way to change credentials or send a 401.

      A 403 doesn't tell the client / user agent what the next step is or provide a way to change credentials.

      So maybe a 302 redirect is the best answer after all? Even though it sadly lacks the nice semantic distinction that 401/403 provide...

    8. FORBIDDEN: Status code (403) indicating the server understood the request but refused to fulfill it. User/agent known by the server but has insufficient credentials. Repeating request will not work, unless credentials changed, which is very unlikely in a short time span.
    9. Send a 302 to your login-page

      That's typically what people do, isn't it.

      That answers the question "how do we best instruct the user agent to take the next step that is required". And maybe a redirect is in fact the best answer.

      See https://hyp.is/mDvXsHoxEeyHC0Ol9HE3CA/stackoverflow.com/questions/3297048/403-forbidden-vs-401-unauthorized-http-responses

    10. The statement is "If the request already included Authorization credentials". That means if this is a response from a request which provided the credential (e.g. the response from a RFC2617 Authentication attempt). It is essentially to allow the server to say, "Bad account/password pair, try again". In the posed question, the user is presumably authenticated but not authorized. 401 is never the appropriate response for those circumstances.
    11. The RFC2617 model is one-user, one-credentials so the case where the user may have a second set of credentials that could be authorized may be ignored. It neither suggests nor implies that some sort of login page or other non-RFC2617 authentication protocol may or may not help - that is outside the RFC2616 standards and definition.
    12. This may be because it is known that no level of authentication is sufficient (for instance because of an IP blacklist), but it may be because the user is already authenticated and does not have authority.
    13. Possibly there are authorizations that will permit access to the resource, possibly there are not, but let's give it a try and see what happens.
    14. 401 is only appropriate for HTTP Authentication
    15. I'm using both - the 401 for unauthenticated users, the 403 for authenticated users with insufficient permissions.
    16. From your use case, it appears that the user is not authenticated. I would return 401.
    17. There's a problem with 401 Unauthorized, the HTTP status code for authentication errors. And that’s just it: it’s for authentication, not authorization. Receiving a 401 response is the server telling you, “you aren’t authenticated–either not authenticated at all or authenticated incorrectly–but please reauthenticate and try again.” To help you out, it will always include a WWW-Authenticate header that describes how to authenticate.
    18. So, for authorization I use the 403 Forbidden response. It’s permanent, it’s tied to my application logic, and it’s a more concrete response than a 401. Receiving a 403 response is the server telling you, “I’m sorry. I know who you are–I believe who you say you are–but you just don’t have permission to access this resource. Maybe if you ask the system administrator nicely, you’ll get permission. But please don’t bother me again until your predicament changes.”
    19. status code 401 has been removed from that RFC

      Well, technically it is still mentioned,

      1. in an example
      2. with a reference to RFC7235

      It just doesn't have a whole section about it in this RFC. But I think that's not because it's trying to say that it's no longer needed/useful, but rather because this new RFC has nothing to add about it /doesn't feel it necessary to clarify anything about 401s. That's why it simply links to the previous RFC for information about 401.

    20. 401 'Unauthorized' should be 401 'Unauthenticated', problem solved !
    21. UNAUTHORIZED: Status code (401) indicating that the request requires authentication, usually this means user needs to be logged-in (session). User/agent unknown by the server. Can repeat with other credentials. NOTE: This is confusing as this should have been named 'unauthenticated' instead of 'unauthorized'.
    22. Checks are usually done in this order: 404 if resource is public and does not exist or 3xx redirection OTHERWISE: 401 if not logged-in or session expired 403 if user does not have permission to access resource (file, json, ...) 404 if resource does not exist or not willing to reveal anything, or 3xx redirection
    23. +----------------------- | RESOURCE EXISTS ? (if private it is often checked AFTER auth check) +----------------------- | | NO | v YES v +----------------------- 404 | IS LOGGED-IN ? (authenticated, aka user session) or +----------------------- 401 | | 403 NO | | YES 3xx v v 401 +----------------------- (404 no reveal) | CAN ACCESS RESOURCE ? (permission, authorized, ...) or +----------------------- redirect | | to login NO | | YES | | v v 403 OK 200, redirect, ... (or 404: no reveal) (or 404: resource does not exist if private) (or 3xx: redirection)
    24. Special case: Can be used instead of 404 to avoid revealing presence or non-presence of resource

      eh? instead of 404? I would actually say that:

      • 404 is as good or better at avoiding revealing presence or non-presence of resource; probably better because 401 implies that we found the resource but that they needed to be signed in in order to access
      • normally one would use a 404 instead of a 401/403 (usually instead of a 403) to avoid revealing presence or non-presence of resource.

      I think they know which is the correct, as evidenced by how they said about 404 below: "User/agent known but server will not reveal anything about the resource, does as if it does not exist." — I think this must have just been a typo.

    25. I would expect that 401 to be named "Unauthenticated" and 403 to be named "Unauthorized". It is very confusing that 401, which has to do with Authentication,
  4. datatracker.ietf.org datatracker.ietf.org
    1. The server generating a 401 response MUST send a WWW-Authenticate header field (Section 4.1) containing at least one challenge applicable to the target resource.
    2. Should probably make this the canonical URL instead: https://www.rfc-editor.org/rfc/rfc7235

    3. User agents are advised to take special care in parsing the field value, as it might contain more than one challenge, and each challenge can contain a comma-separated list of authentication parameters. Furthermore, the header field itself can occur multiple times.
    1. Next, let’s say that your ticket is correct (so you made through security just fine!) and the gate number in your ticket says “Gate 24” but you walk to Gate 27. The attendant cannot authorize you to go through that gate because it’s not the right gate for your ticket.

      They have these mixed up! (Which is understandable, because 401 is misnamed "Unauthorized but should be named "Unauthenticated")

      Checking if authenticated (which, if it fails the check, should return 401 for authentication error) comes first,

      and then checking if authorized (which, if it fails the check, should return 403 for authorization error)

      See https://hyp.is/wRF7wHopEeynafOqKj81vw/stackoverflow.com/questions/3297048/403-forbidden-vs-401-unauthorized-http-responses

    2. In other words, an “incorrect ticket” is similar to messing up your credentials: wrong username and/or password and you receive back a 403 Forbidden. Using the correct credentials but trying to access a resource that is not allowed for those credentials returns you a 401 Unauthorized.

      They have these mixed up! (Which is understandable, because 401 is misnamed "Unauthorized but should be named "Unauthenticated")

      Checking if authenticated (which, if it fails the check, should return 401 for authentication error) comes first,

      and then checking if authorized (which, if it fails the check, should return 403 for authorization error)

      See for example https://www.loggly.com/blog/http-status-code-diagram/

    3. You can also think that 403 happens before 401, despite the natural number order: you will not receive a 401 until you resolve a 403.

      They have these mixed up! (Which is understandable, because 401 is misnamed "Unauthorized but should be named "Unauthenticated")

      Checking if authenticated (which, if it fails the check, should return 401 for authentication error) comes first,

      and then checking if authorized (which, if it fails the check, should return 403 for authorization error)

      See for example https://www.loggly.com/blog/http-status-code-diagram/

    4. If the ticket is incorrect or damaged, you cannot even go through the airport security: when they check your ticket, it will be refused. You are Forbidden to enter the boarding area of the airport.

      It depends what we mean by "incorrect"/damaged "credentials ("ticket")...

      A. If they are invalid or incorrect in the sense that we can't authenticate them as anyone (as it sounds like you mean with "incorrect" or "damaged") (they're not a user in our database or the password doesn't match a user in our database), then you should actually use 401, meaning that the client can/should try (again) to authenticate with different credentials.

      B. But if by "incorrect" you mean (as it sounds like you mean with "you cannot even go through the airport security: when they check your ticket, it will be refused") that the credentials were valid enough to authenticate you as someone (a user in our database), but that (known( user has insufficient credentials, then correct, it should be a 403 forbidden.

      It's even easier to explain / think about if you just think of 401 as being used for any missing or failed authentication. See:

    5. These two sound pretty similar to me. And to make things even more confusing, 403 “Forbidden” says that the server refuses to “authorize” the request but it’s code 401 that is called “Unauthorized”. 😵
  5. datatracker.ietf.org datatracker.ietf.org
    1. If authentication credentials were provided in the request, the server considers them insufficient to grant access.
    1. 401 Unauthorized The requestor is not authorized to access the resource. This is similar to 402 but is used in cases where authentication is expected but has failed or has not been provided.
    1. You’d like to access the content of the resource but you’re not logged in (so not authenticated yet). The server will return you a 401 error. You need to log in to be able to access the resource.
    2. You’d like to delete the user, but you’re authenticated as a regular user, not as an admin. The server doesn’t allow regular users to perform such requests, so in the result, the server will send you a 403 error. Re-authentication won’t make any difference.
    1. APIs that simply map CRUD actions to HTTP verbs have nothing to do with Application State Transfer. You can call them Web APIs or HTTP APIs, but please don’t call them RESTful.
    2. The key thing about the REST approach is that the server addresses the client state transitions. The state of the client is almost totally driven by the server and, for this reason, discussions on API versioning make little sense, too. All that a client should know about a RESTful interface should be the entry point. The rest should come from the interpretation of server responses.
    3. In fact, most people believe that to build a RESTful API you can simply create an API based on URLs and HTTP verbs. This is absolutely false. This misunderstanding is going around for too long.
    1. software design on the scale of decades: every detail is intended to promote software longevity and independent evolution. Many of the constraints are directly opposed to short-term efficiency. Unfortunately, people are fairly good at short-term design, and usually awful at long-term design
    2. "links": { "deposits": "/accounts/12345/deposits", "withdrawals": "/accounts/12345/withdrawals", "transfers": "/accounts/12345/transfers", "close-requests": "/accounts/12345/close-requests" } } } The response contains these possible follow-up links: POST a deposit, withdrawal, transfer, or close request (to close the account).
    3. The client transitions through application states by selecting from the links within a representation or by manipulating the representation in other ways afforded by its media type. In this way, RESTful interaction is driven by hypermedia, rather than out-of-band information.
    1. The combined stuff is available to components using the page store as $page.stuff, providing a mechanism for pages to pass data 'upward' to layouts.

      This is very interesting, and something I missed before. At first it sounded like stuff was only for higher level layouts to pass down to lower layouts and pages. But now you're telling me it is bi-directional, and also lets you pass stuff from pages up to higher layouts?!

    1. import { goto } from '$app/navigation'; function routeToPage(route: string, replaceState: boolean) { goto(`/${route}`, { replaceState }) } replaceState == true will replace the route instead of adding to the browser history. So, when you click back, you will not go back to the route you came from.
    1. For given hash, OpenStruct constructor only converts its top level keys.require 'ostruct' h = { foo: { bar: 1 } } obj = OpenStruct.new(h) obj.foo # => { bar: 1} obj.foo.bar # => NoMethodError: undefined method `bar' for {:bar=>1}:Hash
    1. It's worth noting that an error can coexist and be returned in a successful request alongside data. This is because in GraphQL a query can have partially failed but still contain some data. In that case CombinedError will be passed to us with graphQLErrors, while data may still be set.
    1. I just got caught out by realising I wasn't wrapping my component in a <Provider> that provides our own GraphQL client because the default context value is a urql client. I get why this is a good default out the box for getting started, but I'd love to disable that so that we can ensure all our components are wrapped with a provider that exposes our custom client.
      • defaults

      • disable defaults/safeguard to make sure you always provide a value

    1. Exchanges are bi-directional. So suppose you have the default order: [dedupExchange, cacheExchange, fetchExchange], then an operation describing the GraphQL request, which is only the intent to send a request, goes from outer to inner, or left to right. It'll reach dedup first, then cache, then fetch. This is the operation stream. The operation result stream goes the other way. fetch might emit a result, which is seen by cache, and then seen by dedup. This is a little abstract and we will need some visuals to make this an accessible concept to everyone. This is how it works because every exchange receives a stream of operations. It can then transform this stream and call forward with an altered stream (so every exchange has full control over filtering, mapping, reducing, timing of operations). Furthermore, every return value of an exchange is a stream of results. This means that the simplest exchange just forwards all operations and returns an unaltered stream of results: ({ forward }) => ops$ => forward(ops$). For your "error exchange" (which we should probably provide by default?) this means that it must come before the fetch exchange: [dedupExchange, cacheExchange, errorExchange, fetchExchange] Specifically, it won't need to alter the operations probably, but it will need to look at the results from the fetchExchange which means it must be outside fetch or come before it. Here's an example of a simple implementation of such an exchange: import { filter, pipe, tap } from 'wonka'; import { Exchange } from 'urql'; export const errorExchange: Exchange = ({ forward }) => ops$ => { return pipe( forward(ops$), tap(({ error }) => { // If the OperationResult has an error send a request to sentry if (error) { // the error is a CombinedError with networkError and graphqlErrors properties sentryFireAndForgetHere() // Whatever error reporting you have } }) ); };

      exchange

    1. It’s important to understand that an implements clause is only a check that the class can be treated as the interface type. It doesn’t change the type of the class or its methods at all. A common source of error is to assume that an implements clause will change the class type - it doesn’t!
    1. We cannot make the above statement reactive because we touch tmpCopyAsTemplates.
    2. All my stores also have a defaultValue property and reset method

      Interesting... why?

    3. // Without cloning this will point to the same object and they'll always be the same. // We'd basically change the object in the store without changing the store. let tmpCopyAsTemplates = deepClone($copyAsTemplates);
    4. Same here, and I think this is not correct. The more I think about it, the more I am convinced it's a wrong mental model.
    5. My case is that I have a component which takes an object as a prop. As the user changes the object's values, they can either Save or Cancel. So in the component I have two variables: value and valueUnsaved. It's similar to the example on my comment above. To avoid mutating the original object directly, I assign valueUnsaved as a deep clone of value. If value is changed outside of the component, valueUnsaved should be updated.
    6. I've said it multiples times and I say it again: in Svelte stores solve all your problems and I love them so much.
    7. updating b should update a as well. updating a will update b back again in the reactive declaration.

      don't quite understand.

      how could this ever update a?

         $: b = a * 2;
      
    8. It works if you always want b to be the value deriving from a. However in the example above, we want the value of b to be temporarily out of sync of a.
    1. I still cannot get over the fact that this is not mentioned in the documentation. I do not want to sound negative or unappreciative towards the work that went into this tool (because it has many awesome parts and awesome people working on it and contributing to it), but I do feel kind of let down that "basic" internal mechanics are not explained at all. You either have to find them out yourself or hope some other programmers did and wrote an article about it.
    2. Sorry, let me rephrase. Is this how it is supposed to work? Because right now it looks like a bug. The documentation is really terribly sparse on this topic.
    1. I ended up writing a custom store that "buffers" sets for both a small time interval and ensuring only one async action is in flight (and triggering an extra round of async processing if a set was seen after the last async action was launched).